Mass Update API

The mass update feature allows you to update the values of specific fields for multiple records in territories or custom views in a module. This API is useful when you want to update the same field for all records in a module, territory, or a custom view.

In this API, the input contains the API names of the fields whose values you want to update, and the record ids, cvids(custom view IDs), or territory_id.

You can update up to 50,000 (fifty thousand) records using this API.

Mass update of records happens in two ways:

  • Scheduler type: When you specify custom view ID and territory ID, a job is scheduled in the background and the system returns a "job_id". Use this job_id in the GET request to get the result.

  • Non-scheduler type: When you specify the record IDs, system updates the records instantly. You can update a maximum of 500 records in a single API call in this type of mass update.

Mass Update Records


To schedule mass update.

Request Details

Request URL


Supported modules

Leads, Accounts, Contacts, Deals, Campaigns, Activities, Solutions, Products, Vendors, Price Books, Quotes, Sales Orders, Purchase Orders, Invoices, and Custom


Authorization: Zoho-oauthtoken d92d4xxxxxxxxxxxxx15f52



Possible module names

leads, accounts, contacts, deals, campaigns, activities, solutions, products, vendors, pricebooks, quotes, salesorders, purchaseorders, invoices, and custom

Possible operation types

UPDATE - To schedule mass update

Sample Request

Copiedcurl ""
-H "Authorization: Zoho-oauthtoken 1000.8cb99dxxxxxxxxxxxxx9be93.9b8xxxxxxxxxxxxxxxf"
-d "@input.json"
Copied//Get instance of RecordOperations Class
$recordOperations = new RecordOperations();
//Get instance of MassUpdateBodyWrapper Class that will contain the request body
$request = new MassUpdateBodyWrapper();
//List of Record instances
$records = array();
$recordClass = 'com\zoho\crm\api\record\Record';
//Get instance of Record Class
$record1 = new $recordClass();
 * Call addKeyValue method that takes two arguments
 * 1 -> A string that is the Field's API Name
 * 2 -> Value
$record1->addKeyValue("City", "Value");
//Add Record instance to the list
array_push($records, $record1);
//Set the list to Records in BodyWrapper instance
// $ids = array("34770616603276");
// $request->setIds($ids);
// $territory = new Territory();
// $territory->setId("34770613051357");
// $territory->setIncludeChild(true);
// $request->setTerritory($territory);
//Call massUpdateRecords method that takes BodyWrapper instance, ModuleAPIName as parameter.
$response = $recordOperations->massUpdateRecords($moduleAPIName, $request);
class MassUpdate{
    public function execute(){
        $curl_pointer = curl_init();
        $curl_options = array();
        $curl_options[CURLOPT_URL] = "";
        $curl_options[CURLOPT_RETURNTRANSFER] = true;
        $curl_options[CURLOPT_HEADER] = 1;
        $curl_options[CURLOPT_CUSTOMREQUEST] = "POST";
        $requestBody = array();
        $recordArray = array();
        $recordObject = array();
        $recordObject["Company"] = "Zoho";
        $recordArray[] = $recordObject;
        $requestBody["data"] =$recordArray;
        $curl_options[CURLOPT_POSTFIELDS]= json_encode($requestBody);
        $headersArray = array();
        $headersArray[] = "Authorization". ":" . "Zoho-oauthtoken " . "1000.30f3a589XXXXXXXXXXXXXXXXXXX4077.dc5XXXXXXXXXXXXXXXXXXXee9e7c171c";
        curl_setopt_array($curl_pointer, $curl_options);
        $result = curl_exec($curl_pointer);
        $responseInfo = curl_getinfo($curl_pointer);
        list ($headers, $content) = explode("\r\n\r\n", $result, 2);
        if(strpos($headers," 100 Continue")!==false){
            list( $headers, $content) = explode( "\r\n\r\n", $content , 2);
        $headerArray = (explode("\r\n", $headers, 50));
        $headerMap = array();
        foreach ($headerArray as $key) {
            if (strpos($key, ":") != false) {
                $firstHalf = substr($key, 0, strpos($key, ":"));
                $secondHalf = substr($key, strpos($key, ":") + 1);
                $headerMap[$firstHalf] = trim($secondHalf);
        $jsonResponse = json_decode($content, true);
        if ($jsonResponse == null && $responseInfo['http_code'] != 204) {
            list ($headers, $content) = explode("\r\n\r\n", $content, 2);
            $jsonResponse = json_decode($content, true);
(new MassUpdate())->execute();
Copiedcvid = '3524033000000087501'
# List to hold Record instances
records = []
record_ids = [3_524_033_000_005_925_034]
(0..0).each do |i|
  record =
  record.add_field_value(Record::Field::Leads.Company, 'asdad')
mass_update_body_wrapper =
# Set the array to data in MassUpdateBodyWrapper instance = records
# Set the array of IDs to MassUpdateBodyWrapper instance
mass_update_body_wrapper.ids = record_ids
# Set the cvid to MassUpdateBodyWrapper instance
mass_update_body_wrapper.cvid = cvid
# Get instance of RecordOperations Class
rr =
# Call massUpdateRecords method that takes MassUpdateBodyWrapper instance, module_api_name as parameter.
response = rr.mass_update_records(module_api_name,mass_update_body_wrapper)
Copiedrequire 'net/http'
require 'json'

class MassUpdate
    def execute
        url =""
        url = URI(url)
        req =
        http =, url.port)
        http.use_ssl = true
        headers["Authorization"]="Zoho-oauthtoken 1000.dfa7XXXXXXXXXXXXXXXXXX84f9665840.c176aeXXXXXXXXXXXX13f3d37a84d"
        headers&.each { |key, value| req.add_field(key, value) }
        request_body = {};
        record_array = [];
        record_object = {};
        record_object["Company"] = "Zoho";

        record_array = [record_object];
        request_body["data"] =record_array; 
        request_json = request_body.to_json
        req.body = request_json.to_s
        status_code = response.code.to_i
        headers = response.each_header.to_h
        print status_code
        print headers
        unless response.body.nil?
            print  response.body
CopiedrecordIDList = List();

input1 = Map();
input1.put("Lead_Source", "Advertisement");

inputList = List();

params = Map();
params.put("data", inputList);
params.put("over_write", true);
params.put("ids", recordIDList);

response = invokeurl
	url :""
	type :POST
	parameters: params.toString()
info response;

In the request, "@input.json" contains the sample input data.

Request JSON Keys

  • cvidstring, mandatory when custom view fields or territory fields are updated

    The custom view ID whose records you want to mass update

  • over_writeboolean, optional

    Used when updating a multi-select picklist field.
    Possible values - true: replaces all the multi-select picklist values with the value specified for mass update.
    false: adds the specified value to the picklist.Default is false.

  • territoryJSON object, mandatory, when territory fields are updated

    Used to update records in that territory.
    Possible keys - id (string): The territory ID to update the records in that territory.
    include_child (boolean): Boolean field to indicate whether you want to mass update the child territory records as well. Default is false.

  • idsJSON array, mandatory, when records are updated by IDs

    Specify the IDs of the records you want to mass update.

Sample Input

CopiedWith cvid and Territory ID
    "data": [
            "Industry": "Education"//field to be updated
    "cvid": "554023000000091515", //custom view ID to mass update records in that custom view
    "territory": {
        "id": "554023000000430409",//ID of the territory to mass update records in that territory
        "include_child": true //include child territory records for mass updation

With Record IDs in the Input 
    "data": [
            "Lead_Source": "Advertisement",
            "Type": "Existing Business",
            "Languages_Known": [
    "over_write": true,
    "ids": [

In the sample input with record IDs, "Languages_Known" is a custom multi-select picklist in the Deals module.

Response JSON Keys

  • codestring

    Indicates the status of mass update

  • detailsJSON object

    Specifies the "job_id" (for scheduler type), modified time and the name and ID of the user who modified the record (for non-scheduler type).

  • created_timeDate Time in ISO8601 format

    Specifies the time period when the record was created.

  • idstring

    Specifies the unique ID (record ID) of the record that was updated.

  • Created_ByJSON Object

    Specifies the name and ID of the user that created the record.

  • messagestring

    Specifies if the record is updated or the reason for error, if any.

  • statusstring

    Specifies the status of the record as updated, error etc.

Possible Errors


    No field found
    Resolution: No field is specified in the input


    Max field limit exceeded
    Resolution: Number of fields to be mass updated has exceeded the allowed limit for that module


    This field cannot be updated in the Mass Update
    Resolution: The specified field is not found in the module or it is not allowed for mass update


    Field cannot be updated as it is associated with a layout rule
    Resolution: The specified field is used as primary in a layout rule


    Field cannot be updated as it is associated with a validation rule
    Resolution: The specified field is used as primary in a validation rule


    Field is not visible
    Resolution: The specified field is made invisible/inaccessible to the user


    The id given seems to be invalid
    Resolution: The record ID, cvid, or territory ID specified is invalid


    The record is in stop processing
    Resolution: The specified record is in the stop processing state


    The record is in blue print
    Resolution: The specified record is in blueprint and user tries to update a blueprint picklist value


    required field not found
    Resolution: No cvid or record ID is specified in the input


    no permission to perform an action on this record
    Resolution: User does not have permission to perform any action on the record


    Already a Mass Action scheduler is running for the given cvid
    Resolution: The records in the custom view specified are already scheduled for mass update


    Record count exceeded
    Resolution: Number of records that can be mass updated has exceeded the maximum allowed limit of 50000


    record not approved
    Resolution: The record with the specified ID is not approved

  • INVALID_DATAHTTP 207 (multi-status)

    In the non-scheduler type request, one of the record IDs is invalid. The valid record IDs get updated, and the invalid IDs throw an error.
    Resolution: Specify valid record IDs in the input.


    no record found to update
    Resolution: There are no records in the custom view specified


    permission denied
    Resolution: User does not have permission to mass update records


    Field Edit Permission not given
    Resolution: User does not have permission to edit the field


    Customview not accessible
    Resolution: Custom view is not accessible to the user or the module


    the module name given seems to be invalid
    Resolution: The module name specified is incorrect. Refer to supported modules section above and specify a valid module API name.


    Please check if the URL trying to access is a correct one
    Resolution: The request URL specified is incorrect. Specify a valid request URL. Refer to request URL section above.


    Resolution: Client does not have ZohoCRM.mass_update.{module_name}.UPDATE scope. Create a new client with valid scope. Refer to scope section above.


    Internal Server Error
    Resolution: Unexpected and unhandled exception in Server. Contact support team.


    The http request method type is not a valid one
    Resolution: You have specified an invalid HTTP method to access the API URL. Specify a valid request method. Refer to endpoints section above.


    User does not have sufficient privilege to schedule mass update.
    Resolution: The user does not have the permission to schedule mass update. Contact your system administrator.


    Cannot update record that is not approved yet
    Resolution: Please wait until the Zia image or the merge duplicates process is complete and try again.


    Cannot update record that is not approved yet

    • Case 1: If the record is in the rejected state due to Zia image validation, either upload a new image (or) delete the failed image and, resubmit the record to Zia image validation.
    • Case 2: If the record is in Zia record approval, the system will not allow you to update the images of the record until the reviewer approves or rejects the record.
  • It is mandatory to specify either custom view ID or record IDs in the input.

  • It is mandatory to specify the custom view ID when you want to mass update records in a territory.

  • You cannot mass update Email, lookup fields, layout fields, multi line fields, and line items.

  • You can mass update up to three fields in the Deals module and only one field in all other modules in a single API call.

  • You can mass update a maximum of 500 records in a single API call when you use the non-scheduler type mass update (i.e with record IDs).

  • You can mass update a maximum of 50,000 (fifty thousand) records in a single API call when you use the scheduler type mass update (i.e by specifying the cvid and territory ID).

  • While mass updating records based on their IDs, if some of the records have invalid data, only those records will not be processed.

  • Use Territories API to get the territory ID.

  • For the non-scheduler type mass update, automation rules such as approvals, blueprints, and workflows are triggered automatically.

  • For the scheduler type mass update, automation rules are triggered automatically when the record count is less than 1000. When the record count is greater than 1000, automation rules do not get triggered.

Sample Response

CopiedResponse for scheduler type
    "data": [
            "code": "SUCCESS",
            "details": {
                "job_id": "554023000000506003"
            "message": "mass update scheduled successfully",
            "status": "success"

Response for non-scheduler type (with record IDs)
    "data": [
            "code": "SUCCESS",
            "details": {
                "Modified_Time": "2021-03-03T12:17:00+05:30",
                "Modified_By": {
                    "name": "Patricia boyle",
                    "id": "554023000000497007"
                "Created_Time": "2021-02-26T19:13:56+05:30",
                "id": "580845000003654076",
                "Created_By": {
                    "name": "Patricia Boyle",
                    "id": "580845000000242009"
            "message": "record updated",
            "status": "success"
            "code": "INVALID_DATA",
            "details": {
                "id": "554023000000497021"
            "message": "the id given seems to be invalid",
            "status": "error"