Insert or Update Records (Upsert)

Purpose

To insert or update a record. The system checks for duplicate records based on the duplicate check field's values. If the record is already present, it gets updated. If not, the record is inserted.

Request Details

Request URL

https://www.zohoapis.com/crm/v2/{module_api_name}/upsert

Supported modules

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

Header

Authorization: Zoho-oauthtoken d92d4xxxxxxxxxxxxx15f52

Scope

scope=ZohoCRM.modules.ALL
(or)
scope=ZohoCRM.modules.{module_name}.{operation_type}

Possible module names

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

Possible operation types

ALL - Full access to the record
WRITE - Edit records in the module
CREATE - Create records in the module

Sample Request

Copiedcurl "https://www.zohoapis.com/crm/v2/Leads/upsert"
-H "Authorization: Zoho-oauthtoken 1000.8cb99dxxxxxxxxxxxxx9be93.9b8xxxxxxxxxxxxxxxf"
-d "@upsertlead.json"
-X POST
3.0.08.0
Copied//API Name of the module to create records
String moduleAPIName = "Leads";

//Get instance of RecordOperations Class
RecordOperations recordOperations = new RecordOperations();

//Get instance of BodyWrapper Class that will contain the request body
BodyWrapper request = new BodyWrapper();

//List of Record instances
List < com.zoho.crm.api.record.Record > records = new ArrayList < com.zoho.crm.api.record.Record > ();

//Get instance of Record Class
com.zoho.crm.api.record.Record record1 = new com.zoho.crm.api.record.Record();

/*
 * Call addFieldValue method that takes two arguments
 * 1 -> Call Field "." and choose the module from the displayed list and press "." and choose the field name from the displayed list.
 * 2 -> Value
 */
record1.addFieldValue(Field.Leads.CITY, "City");

record1.addFieldValue(Field.Leads.LAST_NAME, "Last Name");

record1.addFieldValue(Field.Leads.FIRST_NAME, "First Name");

record1.addFieldValue(Field.Leads.COMPANY, "Company1");

/*
 * Call addKeyValue method that takes two arguments
 * 1 -> A string that is the Field's API Name
 * 2 -> Value
 */
record1.addKeyValue("Custom_field", "Value");

record1.addKeyValue("Custom_field_2", "value");

//Add Record instance to the list
records.add(record1);

//Get instance of Record Class
com.zoho.crm.api.record.Record record2 = new com.zoho.crm.api.record.Record();

/*
 * Call addFieldValue method that takes two arguments
 * 1 -> Call Field "." and choose the module from the displayed list and press "." and choose the field name from the displayed list.
 * 2 -> Value
 */
record2.addFieldValue(Field.Leads.CITY, "City");

record2.addFieldValue(Field.Leads.LAST_NAME, "Last Name");

record2.addFieldValue(Field.Leads.FIRST_NAME, "First Name");

record2.addFieldValue(Field.Leads.COMPANY, "Company12");

/*
 * Call addKeyValue method that takes two arguments
 * 1 -> A string that is the Field's API Name
 * 2 -> Value
 */
record2.addKeyValue("Custom_field", "Value");

record2.addKeyValue("Custom_field_2", "value");

//Add Record instance to the list
records.add(record2);

List < String > duplicateCheckFields = new ArrayList < String > (Arrays.asList("City", "Last_Name", "First_Name"));

request.setDuplicateCheckFields(duplicateCheckFields);

//Set the list to Records in BodyWrapper instance
request.setData(records);
HeaderMap headerInstance = new HeaderMap();
//Call upsertRecords method that takes moduleAPIName and BodyWrapper instance as parameter.
APIResponse < ActionHandler > response = recordOperations.upsertRecords(moduleAPIName, request,headerInstance);
Copiedpackage com.zoho.crm.api.sample.restapi.records;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;
public class InsertorUpdateRecordsUpsert 
{
	@SuppressWarnings("deprecation")
	public static void main(String[] args) 
	{
		try
		{
			HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
			SSLContext sslContext = SSLContext.getDefault();
			SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
			CloseableHttpClient httpclient = httpClientBuilder.setSSLSocketFactory(sslConnectionSocketFactory).build();
			URIBuilder uriBuilder = new URIBuilder("https://www.zohoapis.com/crm/v2/Leads/upsert");
			HttpUriRequest requestObj = new HttpPost(uriBuilder.build());
			HttpEntityEnclosingRequestBase requestBase = (HttpEntityEnclosingRequestBase) requestObj;
			JSONObject requestBody = new JSONObject();
			JSONArray recordArray = new JSONArray();
			JSONObject recordObject = new JSONObject();
			recordObject.put("Last_Name", "Lead_changed");
			recordObject.put("Email", "newcrmapi@zoho.com");
			recordObject.put("Company", "abc");
			recordObject.put("Lead_Status", "Contacted");
			recordArray.put(recordObject);
			recordObject = new JSONObject();
			recordObject.put("Last_Name", "New Lead");
			recordObject.put("First_Name", "CRM Lead");
			recordObject.put("Email", "newlead@zoho.com");
			recordObject.put("Lead_Status", "Attempted to Contact");
			recordObject.put("Mobile", "7685635434");
			recordArray.put(recordObject);
			requestBody.put("data", recordArray);
			JSONArray duplicateCheckFields = new JSONArray();
			duplicateCheckFields.put("Email");
			duplicateCheckFields.put("Company");
			requestBody.put("duplicate_check_fields", duplicateCheckFields);
			JSONArray trigger = new JSONArray();
			trigger.put("approval");
			trigger.put("workflow");
			trigger.put("blueprint");
			requestBody.put("trigger", trigger);
			requestBase.setEntity(new StringEntity(requestBody.toString(), HTTP.UTF_8));
			requestObj.addHeader("Authorization", "Zoho-oauthtoken 1000.xxxxxxx.xxxxxxx");
			HttpResponse response = httpclient.execute(requestObj);
			HttpEntity responseEntity = response.getEntity();
			System.out.println("HTTP Status Code : " + response.getStatusLine().getStatusCode());
			if(responseEntity != null)
			{
				Object responseObject = EntityUtils.toString(responseEntity);
				String responseString = responseObject.toString();
				System.out.println(responseString);
			}
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
		}
	}
}
3.0.07.x
Copied//Get instance of RecordOperations Class that takes moduleAPIName as parameter
$recordOperations = new RecordOperations();
//Get instance of BodyWrapper Class that will contain the request body
$request = new BodyWrapper();
//List of Record instances
$records = array();
$recordClass = 'com\zoho\crm\api\record\Record';
//Get instance of Record Class
$record1 = new $recordClass();
/*
 * Call addFieldValue method that takes two arguments
 * 1 -> Call Field "." and choose the module from the displayed list and press "." and choose the field name from the displayed list.
 * 2 -> Value
*/
$field = new Field("");
$record1->addFieldValue(Leads::City(), "City");
// $record1->addFieldValue(Leads::LastName(), "Last Name");
$record1->addFieldValue(Leads::FirstName(), "First Name");
$record1->addFieldValue(Leads::Company(), "Company1");
/*
 * Call addKeyValue method that takes two arguments
 * 1 -> A string that is the Field's API Name
 * 2 -> Value
*/
$record1->addKeyValue("Custom_field", "Value");
$record1->addKeyValue("Custom_field_2", "value");
//Add Record instance to the list
array_push($records, $record1);
//Get instance of Record Class
$record2 = new $recordClass();
/*
* Call addFieldValue method that takes two arguments
* 1 -> Call Field "." and choose the module from the displayed list and press "." and choose the field name from the displayed list.
* 2 -> Value
*/
$record2->addFieldValue(Leads::City(), "City");
// $record2->addFieldValue(Leads::LastName(), "Last Name");
$record2->addFieldValue(Leads::FirstName(), "First Name");
$record2->addFieldValue(Leads::Company(), "Company12");
/*
* Call addKeyValue method that takes two arguments
 * 1 -> A string that is the Field's API Name
* 2 -> Value
 */
$record2->addKeyValue("Custom_field", "Value");
$record2->addKeyValue("Custom_field_2", "value");
//Add Record instance to the list
array_push($records, $record2);
$duplicateCheckFields = array("City", "Last_Name", "First_Name");
$request->setDuplicateCheckFields($duplicateCheckFields);
//Set the list to Records in BodyWrapper instance
$request->setData($records);
$headerInstance = new HeaderMap();
//Call createRecords method that takes BodyWrapper instance as parameter.
$response = $recordOperations->upsertRecords($moduleAPIName, $request,$headerInstance);
Copied<?php

class UpsertRecords
{
    public function execute(){
        $curl_pointer = curl_init();
        
        $curl_options = array();
        $url = "https://www.zohoapis.com/crm/v2/Leads/upsert";
        
        $curl_options[CURLOPT_URL] =$url;
        $curl_options[CURLOPT_RETURNTRANSFER] = true;
        $curl_options[CURLOPT_HEADER] = 1;
        $curl_options[CURLOPT_CUSTOMREQUEST] = "POST";
        $requestBody = array();
        $recordArray = array();
        $recordObject = array();
        $recordObject["Company"]="FieldAPIValue";
        $recordObject["Last_Name"]="347706107420006";
        $recordObject["First_Name"]="347706107420006";
        $recordObject["State"]="FieldAPIValue";

        
        
        $recordArray[] = $recordObject;
        $requestBody["data"] =$recordArray;
        $curl_options[CURLOPT_POSTFIELDS]= json_encode($requestBody);
        $headersArray = array();
        
        $headersArray[] = "Authorization". ":" . "Zoho-oauthtoken " . "1000.8cb99dxxxxxxxxxxxxx9be93.9b8xxxxxxxxxxxxxxxf";
        
        $curl_options[CURLOPT_HTTPHEADER]=$headersArray;
        
        curl_setopt_array($curl_pointer, $curl_options);
        
        $result = curl_exec($curl_pointer);
        $responseInfo = curl_getinfo($curl_pointer);
        curl_close($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);
        }
        var_dump($headerMap);
        var_dump($jsonResponse);
        var_dump($responseInfo['http_code']);
        
    }
    
}
(new UpsertRecords())->execute();
3.0.08.x
Copied//Get instance of RecordOperations Class
RecordOperations recordOperations = new RecordOperations();
//Get instance of BodyWrapper Class that will contain the request body
BodyWrapper request = new BodyWrapper();
//List of Record instances
List<Com.Zoho.Crm.API.Record.Record> records = new List<Com.Zoho.Crm.API.Record.Record>();
//Get instance of Record Class
Com.Zoho.Crm.API.Record.Record record1 = new Com.Zoho.Crm.API.Record.Record();
/*
* Call addFieldValue method that takes two arguments
* 1 -> Call Field "." and choose the module from the displayed list and press "." and choose the field name from the displayed list.
* 2 -> Value
*/
record1.AddFieldValue(Leads.CITY, "City");
record1.AddFieldValue(Leads.LAST_NAME, "Last Name");
record1.AddFieldValue(Leads.FIRST_NAME, "First Name");
record1.AddFieldValue(Leads.COMPANY, "Company1");
/*
* Call addKeyValue method that takes two arguments
* 1 -> A string that is the Field's API Name
* 2 -> Value
*/
record1.AddKeyValue("Custom_field", "Value");
record1.AddKeyValue("Custom_field_2", "value");
//Add Record instance to the list
records.Add(record1);
//Get instance of Record Class
Com.Zoho.Crm.API.Record.Record record2 = new Com.Zoho.Crm.API.Record.Record();
/*
* Call addFieldValue method that takes two arguments
* 1 -> Call Field "." and choose the module from the displayed list and press "." and choose the field name from the displayed list.
* 2 -> Value
*/
record2.AddFieldValue(Leads.CITY, "City");
record2.AddFieldValue(Leads.LAST_NAME, "Last Name");
record2.AddFieldValue(Leads.FIRST_NAME, "First Name");
record2.AddFieldValue(Leads.COMPANY, "Company12");
/*
* Call addKeyValue method that takes two arguments
* 1 -> A string that is the Field's API Name
* 2 -> Value
*/
record2.AddKeyValue("Custom_field", "Value");
record2.AddKeyValue("Custom_field_2", "value");
//Add Record instance to the list
records.Add(record2);
List<string> duplicateCheckFields = new List<string>() { "City", "Last_Name", "First_Name" };
request.DuplicateCheckFields = duplicateCheckFields;
//Set the list to Records in BodyWrapper instance
request.Data = records;
HeaderMap headerInstance = new HeaderMap();
//Call upsertRecords method that takes moduleAPIName and BodyWrapper instance as parameter.
APIResponse<ActionHandler> response = recordOperations.UpsertRecords(moduleAPIName, request,headerInstance);
Copiedusing System;
using System.IO;
using System.Net;
using System.Text;
using Newtonsoft.Json.Linq;
namespace Com.Zoho.Crm.API.Sample.RestAPI.Records
{
    public class UpsertRecords
    {
        public static void InsertorUpdateRecordsUpsert()
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.zohoapis.com/crm/v2/Leads");
            request.Method = "POST";
            request.Headers["Authorization"] = "Zoho-oauthtoken 1000.abfeXXXXXXXXXXX2asw.XXXXXXXXXXXXXXXXXXsdc2";
            JObject requestBody = new JObject();
            JArray recordArray = new JArray();
            JObject recordObject = new JObject();
            recordObject.Add("Last_Name", "Lead_changed");
            recordObject.Add("Email", "newcrmapi1@zoho.com");
            recordObject.Add("Company", "abc");
            recordObject.Add("Lead_Status", "Contacted");
            recordArray.Add(recordObject);
            recordObject = new JObject();
            recordObject.Add("Last_Name", "New Lead");
            recordObject.Add("First_Name", "CRM Lead");
            recordObject.Add("Email", "newlead1@zoho.com");
            recordObject.Add("Lead_Status", "Attempted to Contact");
            recordObject.Add("Mobile", "1234567890");
            recordArray.Add(recordObject);
            requestBody.Add("data", recordArray);
            JArray duplicateCheckFields = new JArray();
            duplicateCheckFields.Add("Email");
            duplicateCheckFields.Add("Company");
            requestBody.Add("duplicate_check_fields", duplicateCheckFields);
            JArray trigger = new JArray();
            trigger.Add("approval");
            trigger.Add("workflow");
            trigger.Add("blueprint");
            requestBody.Add("trigger", trigger);
            string dataString = requestBody.ToString();
            var data = Encoding.UTF8.GetBytes(dataString);
            int dataLength = data.Length;
            request.ContentLength = dataLength;
            using (var writer = request.GetRequestStream())
            {
                writer.Write(data, 0, dataLength);
            }
            request.KeepAlive = true;
            HttpWebResponse response;
            try
            {
                response = (HttpWebResponse)request.GetResponse();
            }
            catch (WebException e)
            {
                if (e.Response == null) { throw; }
                response = (HttpWebResponse)e.Response;
            }
            HttpWebResponse responseEntity = response;
            Console.WriteLine("HTTP Status Code : " + (int)response.StatusCode);
            string responsestring = new StreamReader(responseEntity.GetResponseStream()).ReadToEnd();
            responseEntity.Close();
            Console.WriteLine(responsestring);
        }
    }
}
3.0.03.x.x
Copied# Get instance of RecordOperations Class
record_operations = RecordOperations()
# Get instance of BodyWrapper Class that will contain the request body
request = BodyWrapper()
# List to hold Record instances
records_list = []
# Get instance of Record Class
record_1 = Record()
# Value to Record's fields can be provided in any of the following ways
"""
Call add_field_value method that takes two arguments
Import the zcrmsdk.src.com.zoho.crm.api.record.field file
1 -> Call Field "." and choose the module from the displayed list and press "." and choose the field name from the displayed list.
2 -> Value
"""
record_1.add_field_value(Field.Leads.last_name(), 'Python SDK')
record_1.add_field_value(Field.Leads.first_name(), 'New')
record_1.add_field_value(Field.Leads.company(), 'Zoho')
record_1.add_field_value(Field.Leads.city(), 'City')
"""
Call add_key_value method that takes two arguments
1 -> A string that is the Field's API Name
2 -> Value
"""
record_1.add_key_value('Custom_field', 'Value')
record_1.add_key_value('Custom_field_2', 12)
# Add Record instance to the list
records_list.append(record_1)
# Get instance of Record Class
record_2 = Record()
# Value to Record's fields can be provided in any of the following ways
"""
Call add_field_value method that takes two arguments
Import the zcrmsdk.src.com.zoho.crm.api.record.field file
1 -> Call Field "." and choose the module from the displayed list and press "." and choose the field name from the displayed list.
2 -> Value
"""
record_2.add_field_value(Field.Leads.last_name(), 'Boyle')
record_2.add_field_value(Field.Leads.first_name(), 'Patricia')
record_2.add_field_value(Field.Leads.company(), 'Law')
record_2.add_field_value(Field.Leads.city(), 'Man')
"""
Call add_key_value method that takes two arguments
1 -> A string that is the Field's API Name
2 -> Value
"""
record_2.add_key_value('Custom_field', 'Value')
record_2.add_key_value('Custom_field_2', 12)
# Add Record instance to the list
records_list.append(record_2)
# Set the list to data in BodyWrapper instance
request.set_data(records_list)
duplicate_check_fields = ["City", "Last_Name", "First_Name"]
# Set the array containing duplicate check fields to BodyWrapper instance
request.set_duplicate_check_fields(duplicate_check_fields)
# Get instance of HeaderMap Class
header_instance = HeaderMap()
# Call upsertRecords method that takes BodyWrapper instance and module_api_name as parameters.
response = record_operations.upsert_records(module_api_name, request,header_instance)
Copieddef upsert_records():
    import requests
    import json

    url = 'https://www.zohoapis.com/crm/v2/Leads/upsert'

    headers = {
        'Authorization': 'Zoho-oauthtoken 1000.04be928e4a96XXXXXXXXXXXXX68.0b9eXXXXXXXXXXXX60396e268',
    }

    request_body = dict()
    record_list = list()

    record_object_1 = {
        'Last_Name': 'Changed-Name',
        'Email': 'newcrmapi@zoho.com',
        'Company': 'Zoho',
        'Lead_Status': 'Contacted',
    }

    record_list.append(record_object_1)

    record_object_2 = {
        'Last_Name': 'New Lead',
        'Email': 'newlead@zoho.com',
        'Lead_Status': 'Attempted to Contact',
        'Phone': '9887766540',
    }

    record_list.append(record_object_2)

    request_body['data'] = record_list

    duplicate_check_fields = ['Email']

    request_body['duplicate_check_fields'] = duplicate_check_fields

    trigger = [
        'approval',
        'workflow',
        'blueprint'
    ]

    request_body['trigger'] = trigger

    response = requests.post(url=url, headers=headers, data=json.dumps(request_body).encode('utf-8'))

    if response is not None:
        print("HTTP Status Code : " + str(response.status_code))

        print(response.json())

upsert_records()
1.0.010.x
Copied//Get instance of RecordOperations Class that takes moduleAPIName as parameter
let recordOperations = new RecordOperations();
//Get instance of BodyWrapper Class that will contain the request body
let request = new BodyWrapper();
//Array to hold Record instances
let recordsArray = [];
//Get instance of Record Class
let record1 = new Record();
/*
 * Call addFieldValue method that takes two arguments
 * Import the "zcrmsdk/core/com/zoho/crm/api/record/field" file
 * 1 -> Call Field "." and choose the module from the displayed list and press "." and choose the field name from the displayed list.
 * 2 -> Value
 */
record1.addFieldValue(Field.Leads.CITY, "City");
record1.addFieldValue(Field.Leads.LAST_NAME, "Last Name");
record1.addFieldValue(Field.Leads.FIRST_NAME, "First Name");
record1.addFieldValue(Field.Leads.COMPANY, "KKRNP");
/*
 * Call addKeyValue method that takes two arguments
 * 1 -> A string that is the Field's API Name
 * 2 -> Value
 */
record1.addKeyValue("Custom_field", "Custom val");
record1.addKeyValue("Custom_field_2", 10);
//Add the record to array
recordsArray.push(record1);
let record2 = new Record();
/*
 * Call addFieldValue method that takes two arguments
 * 1 -> Call Field "." and choose the module from the displayed list and press "." and choose the field name from the displayed list.
 * 2 -> Value
 */
record2.addFieldValue(Field.Leads.CITY, "City");
record2.addFieldValue(Field.Leads.LAST_NAME, "Last Name");
record2.addFieldValue(Field.Leads.FIRST_NAME, "First Name");
record2.addFieldValue(Field.Leads.COMPANY, "KKRNP");
/*
 * Call addKeyValue method that takes two arguments
 * 1 -> A string that is the Field's API Name
 * 2 -> Value
 */
record2.addKeyValue("Custom_field", "Value");
record2.addKeyValue("Custom_field_2", "value");
//Add the record to array
recordsArray.push(record2);
//Set the array to data in BodyWrapper instance
request.setData(recordsArray);
let duplicateCheckFields = ["City", "Last_Name", "First_Name"];
//Set the array containing duplicate check fiels to BodyWrapper instance
request.setDuplicateCheckFields(duplicateCheckFields);
//Get instance of HeaderMap Class
let headerInstance = new HeaderMap();
//Call upsertRecords method that takes BodyWrapper instance and moduleAPIName as parameter.
let response = await recordOperations.upsertRecords(moduleAPIName, request,headerInstance);
Copiedasync function upsertRecords() {
    const got = require("got");

    let url = 'https://www.zohoapis.com/crm/v2/Leads/upsert'

    let headers = {
        Authorization : "Zoho-oauthtoken 1000.354df3680XXXXXXXXXXXXX3.aae0efXXXXXXXXXXXXXXXXXX9"
    }

    let requestBody = {}
    let recordArray = []

    let recordObject1 = {
        'Last_Name': 'Changed-Name',
        'Email': 'newcrmapi@zoho.com',
        'Company': 'Zoho',
        'Lead_Status': 'Contacted',
    }

    let recordObject2 = {
        'Last_Name': 'New Lead',
        'Email': 'newlead@zoho.com',
        'Lead_Status': 'Attempted to Contact',
        'Phone': '9887766540',
    }

    recordArray.push(recordObject1)
    recordArray.push(recordObject2)

    requestBody['data'] = recordArray

    let duplicateCheckFields = ['Email']
    requestBody['duplicate_check_fields'] = duplicateCheckFields

    let trigger = ['approval', 'workflow', 'blueprint']
    requestBody['trigger'] = trigger

    let requestDetails = {
        method : "POST",
        headers : headers,
        body : JSON.stringify(requestBody),
        encoding: "utf8",
        throwHttpErrors : false
    };
    
    let response = await got(url, requestDetails)
    
    if(response != null) {
        console.log(response.statusCode);
        console.log(response.body);
    }
}
upsertRecords()
2.02.x.x
Copied# List to hold Record instances
records = []
# Get instance of Record Class
record = Record::Record.new
# """
# Call add_field_value method that takes two arguments
# 1 -> Call Field "::" and choose the module from the displayed list and press "." and choose the field name from the displayed list.
# 2 -> Value
# """
if module_api_name.downcase == 'Leads'.downcase
  record.add_field_value(Record::Field::Leads.Last_name, 'asdad')
  record.add_field_value(Record::Field::Leads.City, 'City')
  record.add_field_value(Record::Field::Leads.First_name, 'First Name')
  record.add_field_value(Record::Field::Leads.Company, 'KKRNP')
end

# file = Record::FileDetails.new
# file.file_id = "f46166fa14ce16c6e2622b3ce82830759c6334275dc8a317539bbda39a6ca056"
# files = [file]

# """
# Call add_key_value method that takes two arguments
# 1 -> A string that is the Field's API Name
# 2 -> Value
# """

if module_api_name == 'Contacts'
  file_details = []

  file_detail =  Record::FileDetails.new

  file_detail.file_id = '479f0f5eebf0fb982f99e3832b35d23e29f67c2868ee4c789f22579895383c8'

  file_details.push(file_detail)

  record.add_key_value('File_Upload_1', file_details)
end

# """
# Following methods are being used only by Inventory modules
# """
if %w[Quotes Sales_Orders Purchase_Orders Invoices].include? module_api_name
  line_item_product = Record::LineItemProduct.new
  line_item_product.id = 3_477_061_000_005_356_009
  inventory_line_item = Record::InventoryLineItems.new
  inventory_line_item.product = line_item_product
  inventory_line_item.list_price = 10.0
  inventory_line_item.discount = '5.0'
  inventory_line_item.quantity = 123.2
  line_tax = Record::LineTax.new
  line_tax.name = 'Tax1'
  line_tax.percentage = 20.0
  line_taxes = [line_tax]
  inventory_line_item.line_tax = line_taxes
  inventory_line_items = [inventory_line_item]
  record.add_key_value('Product_Details', inventory_line_items)
  record.add_key_value('Subject', 'asd')
end
# """
# Following methods are being used only by Activity modules
# """
if %w[Tasks Events Calls].include? module_api_name
  remind_at = Record::RemindAt.new
  remind_at.alarm = 'FREQ=NONE;ACTION=EMAILANDPOPUP;TRIGGER=DATE-TIME:2020-07-03T12:30:00+05:30'
  who_id =  Record::Record.new
  who_id.id = 3_524_033_000_003_429_023
  record.add_field_value(Record::Field::Tasks.Who_id, who_id)

  participant_record = Record::Participants.new
  participant_record.participant = 'asdasd@gmail.com'
  participant_record.type = 'email'
  record.add_field_value(Record::Field::Events.Remind_at, nil)

  record.add_field_value(Record::Field::Events.Event_title, 'New Automated Event')
  endtime = DateTime.new(2019, 8, 10, 4, 11, 9, '+03:00')
  record.add_field_value(Record::Field::Events.End_datetime, endtime)
  starttime = DateTime.new(2019, 8, 10, 4, 10, 9, '+03:00')
  record.add_field_value(Record::Field::Events.Start_datetime, starttime)

  participants = [participant_record]
  record.add_field_value(Record::Field::Events.Start_datetime, starttime)

  recurring_activity = Record::RecurringActivity.new

  recurring_activity.rrule = 'FREQ=DAILY;INTERVAL=10;UNTIL=2020-08-14;DTSTART=2020-07-03'
  record.add_field_value(Record::Field::Events.Recurring_activity, recurring_activity)
end

if module_api_name == 'Price_Books'
  pricing_detail_record = Record::PricingDetails.new
  pricing_detail_record.from_range = 1.0
  pricing_detail_record.to_range = 1.0
  pricing_detail_record.discount = 1.0
  pricing_detail_records = [pricing_detail_record]
  record.add_key_value('Price_Book_Name', 'assd')
  record.add_field_value(Record::Field::Price_Books.Pricing_details, pricing_detail_records)
  record.add_field_value(Record::Field::Price_Books.Pricing_model, Util::Choice.new('Flat'))
end
# # Get instance of BodyWrapper Class that will contain the request body
records.push(record)
trigger = []
trigger.push('approval')

trigger.push('workflow')

trigger.push('blueprint')
# Get instance of BodyWrapper Class that will contain the request body
body_wrapper = Record::BodyWrapper.new
# Set the list to data in BodyWrapper instance
body_wrapper.data = records
# Set the lar_id in BodyWrapper instance
body_wrapper.lar_id = '213123131'
#set trigger
body_wrapper.trigger = trigger
process = ['review_process']
body_wrapper.process = process
# Get instance of RecordOperations Class
rr = Record::RecordOperations.new
# Get instance of HeaderMap Class
hm = HeaderMap.new
# Call upsertRecords method that takes BodyWrapper instance and module_api_name as parameters.
response = rr.upsert_records(module_api_name,body_wrapper,hm)
Copiedclass UpsertRecords
    def execute
       
        url ="https://www.zohoapis.com/crm/v2/Leads/upsert"
        url = URI(url)
        req = Net::HTTP::Post.new(url.request_uri)
        http = Net::HTTP.new(url.host, url.port)
        http.use_ssl = true
        headers={}
        headers["Authorization"]="Zoho-oauthtoken 1000.50XXXXXXXXX&77e3a.44XXXXXXXXX8353"
        headers&.each { |key, value| req.add_field(key, value) }
       
        request_body = {};
        record_array = [];
        record_object = {};
        record_object["FieldAPIName"] = "FieldAPIValue";  
        record_object["Company"]="FieldAPIValue";
        record_object["Last_Name"]="3477061000007420006";
        record_object["First_Name"]="3477061000007420006";
        record_object["State"]="FieldAPIValue";    
        record_array = [record_object];
        request_body["data"] =record_array; 
        request_json = request_body.to_json
        req.body = request_json.to_s
        response=http.request(req)
        status_code = response.code.to_i
        headers = response.each_header.to_h
        print status_code
        print headers
        unless response.body.nil?
            print  response.body
        end
    end
end

UpsertRecords.new.execute
1.0.0ES6
Copied//Get instance of RecordOperations Class that takes moduleAPIName as parameter
let recordOperations = new ZCRM.Record.Operations();
//Get instance of BodyWrapper Class that will contain the request body
let request = new ZCRM.Record.Model.BodyWrapper();
//Array to hold Record instances
let recordsArray = [];
//Get instance of Record Class
let record1 = new ZCRM.Record.Model.Record();
/*
 * Call addFieldValue method that takes two arguments
 * Import the "zcrmsdk/core/com/zoho/crm/api/record/field" file
 * 1 -> Call Field "." and choose the module from the displayed list and press "." and choose the field name from the displayed list.
 * 2 -> Value
 */
record1.addFieldValue(ZCRM.Record.Model.Field.Leads.CITY, "City");
record1.addFieldValue(ZCRM.Record.Model.Field.Leads.LAST_NAME, "Last Name");
record1.addFieldValue(ZCRM.Record.Model.Field.Leads.FIRST_NAME, "First Name");
record1.addFieldValue(ZCRM.Record.Model.Field.Leads.COMPANY, "KKRNP");
/*
 * Call addKeyValue method that takes two arguments
 * 1 -> A string that is the Field's API Name
 * 2 -> Value
 */
record1.addKeyValue("Custom_field", "Custom val");
record1.addKeyValue("Custom_field_2", 10);
//Add the record to array
recordsArray.push(record1);
let record2 = new ZCRM.Record.Model.Record();
/*
 * Call addFieldValue method that takes two arguments
 * 1 -> Call Field "." and choose the module from the displayed list and press "." and choose the field name from the displayed list.
 * 2 -> Value
 */
record2.addFieldValue(ZCRM.Record.Model.Field.Leads.CITY, "City");
record2.addFieldValue(ZCRM.Record.Model.Field.Leads.LAST_NAME, "Last Name");
record2.addFieldValue(ZCRM.Record.Model.Field.Leads.FIRST_NAME, "First Name");
record2.addFieldValue(ZCRM.Record.Model.Field.Leads.COMPANY, "KKRNP");
/*
 * Call addKeyValue method that takes two arguments
 * 1 -> A string that is the Field's API Name
 * 2 -> Value
 */
record2.addKeyValue("Custom_field", "Value");
record2.addKeyValue("Custom_field_2", "value");
//Add the record to array
recordsArray.push(record2);
//Set the array to data in BodyWrapper instance
request.setData(recordsArray);
let duplicateCheckFields = ["City", "Last_Name", "First_Name"];
//Set the array containing duplicate check fiels to BodyWrapper instance
request.setDuplicateCheckFields(duplicateCheckFields);
//Call upsertRecords method that takes BodyWrapper instance and moduleAPIName as parameter.
let response = await recordOperations.upsertRecords(moduleAPIName, request);
Copiedvar listener = 0;
class InsertorUpdateRecordsUpsert {

	async insertorUpdateRecordsUpsert()	{
		var url = "https://www.zohoapis.com/crm/v2/Leads/upsert"
        var parameters = new Map()
        var headers = new Map()
        var token = {
            clientId:"1000.NPY9M1V0XXXXXXXXXXXXXXXXXXXF7H",
            redirectUrl:"http://127.0.0.1:5500/redirect.html",
            scope:"ZohoCRM.users.ALL,ZohoCRM.bulk.read,ZohoCRM.modules.ALL,ZohoCRM.settings.ALL,Aaaserver.profile.Read,ZohoCRM.org.ALL,profile.userphoto.READ,ZohoFiles.files.ALL,ZohoCRM.bulk.ALL,ZohoCRM.settings.variable_groups.ALL"
        }
        var accesstoken = await new InsertorUpdateRecordsUpsert().getToken(token)
        headers.set("Authorization", "Zoho-oauthtoken " + accesstoken)
        var requestMethod = "POST"
        var reqBody = {"data":[{"Last_Name":"Lead_changed","Email":"newcrmapi@zoho.com","Company":"abc","Lead_Status":"Contacted"},{"Last_Name":"New Lead","Email":"newlead@zoho.com","Company":"abc","Lead_Status":"Contacted"}],"duplicate_check_fields":["Email","Company"],"trigger":["approval","workflow","blueprint"]}
        var params = "";
        parameters.forEach(function(value, key) {
            if (parameters.has(key)) {
                if (params) {
                    params = params + key + '=' + value + '&';
                }
                else {
                    params = key + '=' + value + '&';
                }
            }
        });
        var apiHeaders = {};
        if(headers) {
            headers.forEach(function(value, key) {
                apiHeaders[key] = value;
            });
        }
        if (params.length > 0){
            url = url + '?' + params.substring(0, params.length - 1);
        }
        var requestObj = {
            uri : url,
            method : requestMethod,
            headers : apiHeaders,
            body : JSON.stringify(reqBody),
            encoding: "utf8",
            allowGetBody : true,
			throwHttpErrors : false
        };
        var result = await new InsertorUpdateRecordsUpsert().makeAPICall(requestObj);
        console.log(result.status)
        console.log(result.response)
	}

    async getToken(token) {

        if(listener == 0) {

            window.addEventListener("storage", function(reponse) {
                if(reponse.key === "access_token" && (reponse.oldValue != reponse.newValue || reponse.oldValue == null)){
                    location.reload();
                }
                if(reponse.key === "access_token"){

                    sessionStorage.removeItem("__auth_process");
                }
            }, false);
            listener = 1;
            if(sessionStorage.getItem("__auth_process")) {
                sessionStorage.removeItem("__auth_process");
            }
        }
        ["granted_for_session", "access_token","expires_in","expires_in_sec","location","api_domain","state","__token_init","__auth_process"].forEach(function (k) {
            var isKeyExists = localStorage.hasOwnProperty(k);
            if(isKeyExists) {
                sessionStorage.setItem(k, localStorage[k]);
            }
            localStorage.removeItem(k);
        });
        var valueInStore = sessionStorage.getItem("access_token");
        var tokenInit = sessionStorage.getItem("__token_init");
        if(tokenInit != null && valueInStore != null && Date.now() >= parseInt(tokenInit) + 59 * 60 * 1000){ // check after 59th minute
            valueInStore = null;
            sessionStorage.removeItem("access_token");
        }

        var auth_process = sessionStorage.getItem("__auth_process");
        if ((valueInStore == null && auth_process == null) || (valueInStore == 'undefined' && (auth_process == null || auth_process == "true"))) {
            var accountsUrl = "https://accounts.zoho.com/oauth/v2/auth"
            var clientId;
            var scope;
            var redirectUrl;
            if(token != null) {
                clientId = token.clientId;
                scope = token.scope;
                redirectUrl = token.redirectUrl;
            }

            var fullGrant = sessionStorage.getItem("full_grant");
            var grantedForSession = sessionStorage.getItem("granted_for_session");
            if(sessionStorage.getItem("__token_init") != null && ((fullGrant != null && "true" == full_grant) || (grantedForSession != null && "true" == grantedForSession))) {
                accountsUrl += '/refresh';
            }
            if (clientId && scope) {
                sessionStorage.setItem("__token_init", Date.now());
                sessionStorage.removeItem("access_token");
                sessionStorage.setItem("__auth_process", "true");
                window.open(accountsUrl + "?" + "scope" + "=" + scope + "&"+ "client_id" +"=" + clientId + "&response_type=token&state=zohocrmclient&redirect_uri=" + redirectUrl);
                ["granted_for_session", "access_token","expires_in","expires_in_sec","location","api_domain","state","__token_init","__auth_process"].forEach(function (k) {
                    var isKeyExists = localStorage.hasOwnProperty(k);
                    if(isKeyExists){
                        sessionStorage.setItem(k, localStorage[k]);
                    }
                    localStorage.removeItem(k);
                });
                valueInStore = sessionStorage.getItem("access_token");
            }
        }
        if(token != null && valueInStore != 'undefined'){
            token.accessToken = valueInStore;
        }
        return token.accessToken;
    }

    async makeAPICall(requestDetails) {
        return new Promise(function (resolve, reject) {
            var body, xhr, i;
            body = requestDetails.body || null;
            xhr = new XMLHttpRequest();
            xhr.withCredentials = true;
            xhr.open(requestDetails.method, requestDetails.uri, true);
            for (i in requestDetails.headers) {
                xhr.setRequestHeader(i, requestDetails.headers[i]);
            }
            xhr.send(body);
            xhr.onreadystatechange = function() {
                if(xhr.readyState == 4) {
                    resolve(xhr);
                }
            }
        })
    }
}
CopiedSyntax:
<response> = zoho.crm.upsert(<module>,<values>,<optional_data>,<[connection>]);
mandatory : module,dataMap

Sample Request:
resp = zoho.crm.upsert("Leads", {"Last_Name":"Patricia upsert UF2", "UF":"p.boyle@zylker.com", "Email":"d.grogan@zylker.com"}, {"duplicate_check_fields":["UF" , "Email"]});

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

Note
  • The system checks for duplicate records based on the duplicate check field's values. There are two types of duplicate check fields:

    • The system-defined duplicate check fields - Certain system-generated fields are marked as unique, by default. When you upsert a record, the system checks for duplicate entries in these fields. Refer to System-defined Duplicate Check Fields section below to know the module-wise system-defined duplicate check fields.

    • The user-defined unique fields - The fields for which "Do not allow duplicate values" is enabled. Click here to know more.

  • You can set the order in which the system checks for duplicate records by specifying the duplicate_check_field array in the input. Note that you can add only system-defined duplicate check fields and user-defined unique fields to the duplicate_check_field array.

    Example for the Leads module:

    "duplicate_check_fields": [
    "Email",
    "Phone",
    "Fax"
    ]

    Here, "Email" is the system-defined duplicate check field, and "Phone" and "Fax" are the user-defined unique fields for the Leads module.

  • If you do not specify the duplicate_check_fields, the system checks for duplicate records in this order: system-defined duplicate check fields > user-defined unique fields..

  • The 'INVALID_DATA' error is thrown if the field value length exceeds the maximum length defined for that field.

  • If an API is used inside a Function and the field value length exceeds the limit, then that function receives an error response from the API. For ex: If the max length for a "Text field" is defined as 10, then value given for it in API cannot be "12345678901", since it has 11 characters.

  • A maximum of 100 records can be inserted/updated per API call.

  • You must use only Field API names in the input. You can obtain the field API names from

    • Fields metadata API (the value for the key “api_name” for every field). (Or)

    • Setup > Developer Space > APIs > API Names > {Module}. Choose “Fields” from the “Filter By” drop-down.

  • The trigger input can be workflow, approval, or blueprint. If the trigger is not mentioned, the workflows, approvals and blueprints related to the API will get executed. Enter the trigger value as [] to not execute the workflows.

  • Records with Subform details can also be updated to CRM using the Records API. Please look at Subforms API to learn more about updating subform information within a record.

  • Refer to Response Structure for more details about the JSON keys, values, and their descriptions. You can also use the sample response of each module as the input when you insert, update, or upsert a record in that corresponding module.

  • Refer to Get Records API to know more about field types and limits.

  • Refer to the Insert Records API for the accepted regex patterns for the email, phone, and URL fields.

System-defined Duplicate Check Fields

Following are the default duplicate check fields for different modules.
Leads - Email, Accounts - Account_Name, Contacts - Email, Deals - Deal_Name, Campaigns - Campaign_Name, Cases - Subject, Solutions - Solution_Title, Products - Product_Name, Vendors - Vendor_Name, PriceBooks - Price_Book_Name, Quotes - Subject, SalesOrders - Subject, PurchaseOrders - Subject, Invoices - Subject, CustomModules - Name

To know the specific details about each field type in Zoho CRM and their limitations, refer to Sample Attributes section in Insert Records API.

How does the duplicate check work?

Consider a case where the user has configured two unique fields unique1 and unique2 for a module (user-defined unique fields), and Email is a system-defined unique field.
The following table explains how the duplicate check happens for different user inputs to the duplicate_check_fields array.

User Input to the "duplicate_check_fields" ArrayDuplicate Check Pattern
unique1unique1, unique2
unique2unique2, unique1
unique1, unique2unique1, unique2
EmailEmail, unique1, unique2
No inputSystem-defined duplicate check field for that module followed by unique fields. That is, Email, unique1, unique2

If you do not specify system-defined duplicate check fields in the array, the system will ignore them and check only for user-defined unique fields.

Sample Input

Copied{
    "data": [
        {
            "Last_Name": "Lead_changed",
            "Email": "newcrmapi@zoho.com",
            "Company": "abc",
            "Lead_Status": "Contacted"
        },
        {
            "Last_Name": "New Lead",
            "First_Name": "CRM Lead",
            "Email": "newlead@zoho.com",
            "Lead_Status": "Attempted to Contact",
            "Mobile": "7685635434"
        }
    ],
    "duplicate_check_fields": [
        "Email",
        "Mobile"
    ],
    "trigger":[ "workflow"]
}

Possible Errors

  • INVALID_MODULEHTTP 400

    The module name given seems to be invalid
    Resolution: You have specified an invalid module name or there is no tab permission, or the module could have been removed from the available modules. Specify a valid module API name.

  • INVALID_MODULEHTTP 400

    The given module is not supported in API
    Resolution: The modules such as Documents and Projects are not supported in the current API. (This error will not be shown, once these modules are been supported). Specify a valid module API name.

  • INVALID_DATAHTTP 202

    invalid data
    Resolution: The input specified is incorrect. Specify valid input.

  • INVALID_URL_PATTERNHTTP 404

    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.

  • OAUTH_SCOPE_MISMATCHHTTP 401

    Unauthorized
    Resolution: Client does not have ZohoCRM.modules.{module_name}.WRITE/ZohoCRM.modules.{module_name}.CREATE scope. Create a new client with valid scope. Refer to scope section above.

  • NO_PERMISSIONHTTP 403

    Permission denied to upsert
    Resolution: The user does not have permission to upsert records. Contact your system administrator.

  • INTERNAL_ERRORHTTP 500

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

  • INVALID_REQUEST_METHODHTTP 400

    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.

  • AUTHORIZATION_FAILEDHTTP 400

    User does not have sufficient privilege to upsert records.
    Resolution: The user does not have the permission to upsert record details. Contact your system administrator.

  • MANDATORY_NOT_FOUNDHTTP 202

    required field not found
    Resolution: You have not specified one or more mandatory fields in the input. Refer to Fields Metadata API to know the mandatory fields.

Sample Response

Copied{
    "data": [
        {
            "code": "SUCCESS",
            "duplicate_field": "Email",
            "action": "update",
            "details": {
                "Modified_Time": "2020-10-14T10:31:43+05:30",
                "Modified_By": {
                    "name": "Patricia Boyle",
                    "id": "4150868000000225013"
                },
                "Created_Time": "2019-09-11T16:21:15+05:30",
                "id": "4150868000000376008",
                "Created_By": {
                    "name": "Patricia Boyle",
                    "id": "4150868000000225013"
                }
            },
            "message": "record updated",
            "status": "success"
        },
        {
            "code": "SUCCESS",
            "duplicate_field": null,
            "action": "insert",
            "details": {
                "Modified_Time": "2020-10-14T10:31:43+05:30",
                "Modified_By": {
                    "name": "Patricia Boyle",
                    "id": "4150868000000225013"
                },
                "Created_Time": "2020-10-14T10:31:43+05:30",
                "id": "4150868000003194003",
                "Created_By": {
                    "name": "Patricia Boyle",
                    "id": "4150868000000225013"
                }
            },
            "message": "record added",
            "status": "success"
        }
    ]
}