Kaizen #177: Duplicate Check Preferences API vs. Upsert API

Kaizen #177: Duplicate Check Preferences API vs. Upsert API

Hello all!!!

Welcome back to another week of Kaizen. Last week, we discussed Optimizing the Use of Record ID Variables in Zoho CRM Queries.

This week, we will explore two important APIs for managing duplicate records in Zoho CRM - Duplicate Check Preferences API and Upsert Records API. While both of these APIs help manage duplicate records, they serve different purposes and are to be used in different scenarios. 




This post covers:
  • What is the Duplicate Check Preferences API?
    • Use Case
    • Duplicate Check Configurations
    • Updating Duplicate Check Configuration
    • How Duplicate Check Preferences Work During Record Creation/Update?
  • What is the Upsert API?
    • Use Case
  • Differences between Duplicate Check Preferences API and Upsert API

What is the Duplicate Check Preferences API

The Duplicate Check Preferences API is a configuration API that allows you to set up criteria using unique fields to manage duplicates across Leads module including Converted Leads and Contacts
in Zoho CRM. Based on the given criteria, the system will restrict the creation or update of duplicate records. For example, if the Phone field is marked as unique and set for duplicate checks, the system will make sure that no two records have the same phone number during records creation or update.

With the Duplicate Check Preferences API, you can define criteria to find duplicates, such as matching email addresses, phone numbers, or custom fields. During record creation or update, Zoho CRM checks the configured criteria against converted leads or contacts. If a match is found, it triggers a "DUPLICATE_DATA" error and blocks duplicates based on your configuration.

By default, the Insert Records API and Update Records API automatically check for this configuration. If a record matches the defined duplicate criteria, the system prevents its creation or update.

Use case

Zylker, a sales team managing customer contacts in Zoho CRM, often imports leads from various sources like website forms, events, and campaigns. However, the team noticed that many duplicate contacts are being created because the same phone number is associated with some of the contacts. This creates confusion and results in redundant work in their sales process.
By using the Duplicate Check Preferences API, Zylker can prevent the anymore duplicate contacts based on phone numbers (phone is used for an example).

Duplicate Check Configurations

In Zoho CRM, you can configure duplicate check preferences via API in two ways. 

i. Configuration in Leads module
The system checks for duplicates on all the Leads using the specified unique fields. By selecting this option, the duplicates will be checked on all the Converted Leads (custom view) as well. This configuration is applicable across all the layouts.
The following is the configuration for duplicate check in the Leads module via API. 

Request Method: POST

Note:
  • The "module" parameter is mandatory, and its supported value is Leads. 
  • The above URL applies to both Leads and Contacts module configurations.
  •  You must mark at least one field as mandatory. So, the system can check for duplicates based on the value in the unique field within the Leads module when creating a record.
Input JSON

{
    "duplicate_check_preference": {
        "type": "converted_records", //Converted Leads custom view in Leads module
    }
}


Response

{
    "duplicate_check_preference": {
        "code": "SUCCESS",
        "details": {},
        "message": "Duplicate check enabled for converted_records successfully.",
        "status": "success"
    }
}




ii. Configuration in Contacts module

By selecting this option, the system will check for duplicates in the Contacts module using mapped fields.

Input JSON

{
    "duplicate_check_preference": {
        "type": "mapped_module_records",
        "type_configurations": [
            {
                "field_mappings": [
                    {
                        "current_field": {
                            "api_name": "Email",
                            "id": "5725767000000002601"
                        },
                        "mapped_field": {
                            "api_name": "Email",
                            "id": "5725767000000002503"
                        }
                    }
                ],
                "mapped_module": {
                    "api_name": "Contacts",
                    "id": "5725767000000002179"
                }
            }
        ]
    }
}


The "Phone" field from both the Leads and Contacts modules is mapped to identify duplicate records.

How Duplicate Check Preferences Work During Record Creation/Update

Consider Zylker has configured the Contacts module ("type":"mapped_module_records") to check duplicate contacts.
For example, a sales representative at Zylker attempts to add a contact from the Cold Call lead source. However, the same contact already exists in the Contacts module, either from the same or a different lead source.
Since the Contacts module is configured for duplicate check preferences, the system will check for duplicates in the Contacts module using mapped fields. During the record insertion action, the system verifies the Contacts module for any matching records based on these unique identifiers. Based on the result, it either creates the record or throws an error.

Use the Insert Records API to create records in a module.

Request Method: POST

Input JSON

{
    "data": [
        {
            "Company": "Villa Margarita",
            "Last_Name": "Dolan",
            "First_Name": "Brian",
            "Email": "brian@villa.com",
            "Phone": "12345",
            "State": "Texas"
        }
    ]
}


Response


 {

    "data": [

        {

            "code": "DUPLICATE_DATA",

            "details": {

                "api_name": "Email",

                "duplicate_record": {

                    "Owner": {

                        "name": "Patricia Boyle",

                        "id": "5725767000000411001",

                        "zuid": "808233918"

                    },

                    "module": {

                        "api_name": "Contacts",

                        "id": "5725767000000002179"

                    },

                    "id": "5725767000000774010" //The record that already exists in the Contacts module.

                },

                "json_path": "$.data[0].Email",

                "more_records": false

            },

            "message": "duplicate data",

            "status": "error"

        }

    ]

}


Duplicates are also checked during record updates. If a record is updated with a value that already exists in a unique field, the system indicates it as a duplicate and returns a "DUPLICATE_DATA" error.

Update Duplicate Check Configuration

To update the previously enabled Duplicate Check option configured in your account, use the Update Duplicate Check Option API.


The Contacts ("type": "mapped_module_records") configuration is used in the below sample input. 


{
    "duplicate_check_preference": {
        "type": "mapped_module_records",
        "type_configurations": [
            {
                "field_mappings": [
                    {
                        "mapped_field": {
                            "api_name": "Phone", //The previously configured Email field as a unique identifier in Contacts has now been replaced with the Phone field.
                            "name": "Contacts",
                            "id": "5725767000000411001"
                        },
                        "current_field": {
                            "api_name": "Phone",
                            "name": "Leads", //The previously configured Email field as a unique identifier in Leads has now been replaced with the Phone field.
                            "id": "5725767000005381030"
                        }
                    }
                ],
                "mapped_module": {
                    "api_name": "Contacts",
                    "name": "Contacts",
                    "id": "5725767000000002179"
                }
            }
        ]
    }
}

You can also retrieve and delete duplicate configuration.

What is the Upsert API?

The Upsert API is a combination of "update" and "insert". 


How it works?

  • You provide a unique identifier (e.g., email, phone number, or a custom field) to check for existing records.

  • If a record with the same identifier exists, it updates that record.

  • If no matching record is found, it creates a new one.

Flow diagram

Use Case 

Zylker, an e-commerce company, uses Zoho CRM to manage customer data. Customers sign up on Zylker’s online store, and their details are stored in the e-commerce platform like Shopify. Over time, customers may update their contact information, or new customers may sign up. To keep customer records in Zoho CRM accurate and avoid duplicates, Zylker uses the Upsert API to:
  • Update existing customer records details if the given unique identifier, such as email or phone number, matches an existing record in Zoho CRM.
  • Insert a new record if no match is found.  This way, Zylker ensures that new customers are added efficiently.

There are two types of duplicate check fields:

i. System-defined duplicate check fields.
ii. User-defined duplicate check fields.

i. System-defined duplicate check fields
The table below lists the system-defined unique fields. When you create a record using the Upsert API, the system checks these fields for duplicate entries. 

Leads

Email

Contacts

Email

Accounts

Account_Name

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

Custom Module

Name


ii.
User-defined duplicate check fields
You can set a normal field as a duplicate check field by enabling "Do not allow duplicate values." Note that you can only set fields with the following field-types as unique— Single Line, Email, Phone, Number, Long Integer, and URL.


Request Method: POST

Sample Input JSON

Here, "Email," a system-defined field, has been used as a duplicate check field.
{
    "data": [
        {
            "Email": "alice@mail.com",
            "First_Name": "Alice",
            "Last_Name": "Brown",
            "Phone": "+1-555-222-3333",
            "Order_Date": "2024-01-10",
            "Order_Value": "$175.00"
        },
        {
            "Email": "pat@mail.com",
            "First_Name": "pat",
            "Last_Name": "Davis",
            "Phone": "+1-555-666-7777",
            "Order_Date": "2024-01-15",
            "Order_Value": "$300.00"
        }
    ],
    "duplicate_check_fields": [
        "Email" //You can set the order in which the system checks for duplicate records by specifying the duplicate_check_field array in the input. 
    ]
}

Response


{
    "data": [
        {
            "code": "SUCCESS",
            "duplicate_field": null,
            "action": "insert",
            "details": {
                "Modified_Time": "2025-02-08T09:43:08-08:00",
                "Modified_By": {
                    "name": "Patricia Boyle",
                    "id": "5725767000000411001"
                },
                "Created_Time": "2025-02-08T09:43:08-08:00",
                "id": "5725767000005425036",
                "Created_By": {
                    "name": "Patricia Boyle",
                    "id": "5725767000000411001"
                }
            },
            "message": "record added",
            "status": "success"
        },
        {
            "code": "SUCCESS",
            "duplicate_field": "Email",
            "action": "update",
            "details": {
                "Modified_Time": "2025-02-08T09:43:08-08:00",
                "Modified_By": {
                    "name": "Patricia Boyle",
                    "id": "5725767000000411001"
                },
                "Created_Time": "2025-02-08T08:52:22-08:00",
                "id": "5725767000005425002",
                "Created_By": {
                    "name": "Patricia Boyle",
                    "id": "5725767000000411001"
                }
            },
            "message": "record updated",
            "status": "success"
        }
    ]
}


For more details on how the Upsert API works, refer to the Kaizen #56 - Upsert Records #API.

Differences between Duplicate Check Preferences API and Upsert API

 

                Duplicate Check API

                           Upsert API

Duplicate Check Preferences can be enabled only in the Leads module.

Supports all modules.

Throws a "DUPLICATE_DATA" error if a duplicate is detected.

Updates the existing record with new field values if a match is found for the unique fields; otherwise, inserts a new record.


Use the above Zoho CRM APIs which fit your use cases.
---------------------------------------------------------------------------------------------------------------------

We trust that this post meets your needs and is helpful. Let us know your thoughts in the comment section or reach out to us at support@zohocrm.com 
Stay tuned for more insights in our upcoming Kaizen posts!

Info

    • Sticky Posts

    • Kaizen #198: Using Client Script for Custom Validation in Blueprint

      Nearing 200th Kaizen Post – 1 More to the Big Two-Oh-Oh! Do you have any questions, suggestions, or topics you would like us to cover in future posts? Your insights and suggestions help us shape future content and make this series better for everyone.
    • Kaizen #226: Using ZRC in Client Script

      Hello everyone! Welcome to another week of Kaizen. In today's post, lets see what is ZRC (Zoho Request Client) and how we can use ZRC methods in Client Script to get inputs from a Salesperson and update the Lead status with a single button click. In this
    • Kaizen #222 - Client Script Support for Notes Related List

      Hello everyone! Welcome to another week of Kaizen. The final Kaizen post of the year 2025 is here! With the new Client Script support for the Notes Related List, you can validate, enrich, and manage notes across modules. In this post, we’ll explore how
    • Kaizen #217 - Actions APIs : Tasks

      Welcome to another week of Kaizen! In last week's post we discussed Email Notifications APIs which act as the link between your Workflow automations and you. We have discussed how Zylker Cloud Services uses Email Notifications API in their custom dashboard.
    • Kaizen #216 - Actions APIs : Email Notifications

      Welcome to another week of Kaizen! For the last three weeks, we have been discussing Zylker's workflows. We successfully updated a dormant workflow, built a new one from the ground up and more. But our work is not finished—these automated processes are
    • Recent Topics

    • Create case via email

      Good Afternoon, I have just registered and am taking a look around the system. Is it possible to create a case via email.  I.e. an employee/client/supplier emails a certain address and that auto generates the case which then prompts a member of staff
    • Locked Notebook

      Hi, I hadn't used my Notebook in some time and was refamiliarizing myself with it. I clicked a lock icon and now I can't unlock. When I hit the information or unlock icons I'm taken to a page with the notebook icon and a keyboard. When I type, nothing
    • Hide fields only for creation

      Hello, I'd like to hide some fields only during the creation of a contact in Zoho CRM. In fact I have some fields that are automatically calculated thanks to an automation, so when my users create a contact I don't want them to fill those fields. I know
    • Issues with Zoho Sheet in Mac

      I have downloaded the Zoho App from App Store but It is failing to Save As, Open & Download Operations. App Store
    • Weekly Sales Summary

      Is it possible to generate a weekly report in Zoho Books to show -$$ amount of estimates generated -# of estimates generated by Salesperson -$$ amount of Sales Orders created -$$ amount of Invoices generated
    • OpenAPI Specs are just plain wrong

      The provided yml files for generating the OpenAPI specs are absolutely riddled with errors and inconsistencies. From missing fields on the objects, to just incorrectly named resource objects. I'm having to go through and manually changing the spec to
    • Add Account column to Invoice screen

      Please show the account column on Invoice creation screen. It is an unnecessary step to have to click add additional info and then select the account for line item. Example : on the bill creation screen when entering description we can easily code it against an account. On the invoice screen it requires additional click. Adding the column on the Invoice screen will make it faster to enter transactions. We currently have 5-6 different accounts that we code line items against, You can imagine the extra
    • Custom Footer – Zoho Writer Document

      Hello everyone, I’m having an issue adding a custom footer in a Zoho Writer document. I would like to insert my company information (including a logo + address) in the footer. The problem is that when I add these elements, the main content of my pages
    • Report grouping

      I have added a grouping in a report but it is not working how i had expected. I wanted to group a summary on a field named Size but when i add the grouping the report is still showing me each record and making a summary at the bottom of the report. What
    • Social Media Simplified with Zoho Social: Preview your Instagram grid before posting

      For a platform like Instagram that relies on visual appeal, it's important that you plan your image and video content in a way that holds your audience's attention. Planning your grid ahead of time gives you the benefit of understanding how your posts
    • Error code 1000

      Can you please tell me why the following, occasionally causes this error via the api, not every time ?... zoho.books.updateRecord("salesorders",organizationID,salesorderID,{"template_id":"#################069","custom_fields":[{"label":"DelDate","value":"Tuesday,
    • VAT rates - exempt and out of scope

      Good Evening, UK based company here. I am a bit confused in respect of setting up VAT rates for exempt goods and services; at present I am simply leaving the VAT rate blank in the transactions in order to prevent any VAT appearing in the VAT return. When
    • How to loop through Multiple Upload and Display Actual File Name

      I have been reading the help on the File Upload Control and reviewed the Deluge help on files and I can not figure out how to loop through the uploaded files and do anything but get the automatically created file names. The code below will run but each
    • abou arattai

      I want to use the Arattai app for business purposes, so please convert my account to a business account.I have my own invoice app, and I want to link it with the Arattai app for direct messaging.
    • Configurable Zoho Cliq Notifications for Zoho People Alerts

      Hello Zoho People Product Team, Greetings and hope you are doing well. We would like to request an enhancement to Zoho People notifications, enabling a native delivery via Zoho Cliq with admin-level control, similar to the notification settings available
    • Looking back at Zoho Calendar in 2025

      Hello Zoho Calendar Community, As we step into a brand-new year, we’d like to take a moment to thank you for being an active and valued part of the Zoho Calendar community. Your trust, feedback, and continued engagement motivate us to keep evolving and
    • There was an error while connecting to GSTN

      I am trying to file GSTR1. Everything flows smoothly until I reach the final step of filing the return. After I enter the PAN and OTP for filing it raises the error "There was an error while connecting to GSTN"
    • Zoho Books Extension: What Happens If Custom Fields Already Exist?

      When developing Zoho Books extensions, what happens if the target Zoho Books organization already has a custom field with the same API name as one defined in the extension? I’m asking because we originally created an on-Books version of this functionality,
    • Internal Server Error (500) When Attempting to View Banking Transactions

      I am experiencing an Internal Server Error (500) when attempting to view transactions across all of my banking accounts. Despite multiple attempts to resolve this, I have received little more than runaround from support, and the issue remains unresolved.
    • How do I add a blank line to the Organisation Address Format?

      I'd like to have my VAT number, for example, shown prominently by having a clear gap between it and the address block above, but any blank lines in the address format get ignored in PDF outputs.
    • Automatic Invoice Number generation for createRecord

      Hello, while testing some custom Buttons in my Zoho Books application, I noticed that I get an error that previously did not occur. After some further digging I found that the automatic transaction numbering of invoices no longer work in my organization.
    • Adding number of days to an estimate.

      I need both QTY of item and "number of days hire" in my estimates at the line item level. Any clues as to how this is done would be greatly appreciated. It needs to calculate. Thanks J
    • Books Api: listing expenses created after certain dates

      Is there any parameter I can add to the List Expenses endpoint that will let me look up expenses by when they were created?
    • Why can't we change the Account type from an Expense to an Asset?

      Like the question. Why in QuickBooks for example if I mistakenly created an account as an expenses and I already captured information in those accounts, I can just change the account type from expense to asset
    • Is it possible to do validation for the Actions added to Reports?

      We have an all-around On Validate function that checks all the possibilities before the Created/Edited form submissions. We want to have a button in the report view, so we can change records without entering. We are able to add this button, and it does
    • [Free Webinar] Environments in Zoho Creator - Creator Tech Connect

      Hello Everyone, We’re delighted to kick off the 2026 edition of the Zoho Creator Tech Connect Series and are excited to continue this learning journey with you. The Creator Tech Connect series is a free monthly webinar featuring deep-dive technical sessions
    • Zoho Voice API SMS

      I made a post request in Zapier to try to send an SMS. Authentication appears to be configured correctly. I followed the documentation and I'm getting a 400 Error "Internal Server Error". Not helpful at all. Anyways, I could not find any information on
    • How do I change (error) display messages

      Hi! I would like to edit display messages like "invalid entries" and "enter a value for Nome" and so on into Italian language messages. How can I do that? Already tried on Validate on form submit. Where I am failing? Thanks in advance.
    • Record Overseas Transactions Along with CC charges

      Hi All, We receive payments via stripe in multiple currencies and stripe takes around 2.5% fees. The amount is settled in INR into our local bank. What should be the currency of the income account used for Stripe payments? Here is a sample flow that we
    • Easier onboarding for new users with stage descriptions

      Greetings, I hope all of you are doing well. We're happy to announce a recent enhancement we've made to Bigin. You can now add descriptions to the stages in your pipeline. Previously, when creating a pipeline, you could only add stages. With this update,
    • Pieds de page personnalisé - Document Zoho Writer

      Bonjour à tous, Je rencontre un souci avec l’ajout d’un pied de page personnalisé dans un document Zoho Writer. Je souhaite insérer les informations de mon entreprise (notamment un logo + adresse) dans le pied de page. Le problème, c’est que lorsque j’ajoute
    • Credit card transactions are backwards after importing statements

      I am new to Zoho Books so I'm importing my firm's bank and credit card statements in. My credit card statements have a single column with negative numbers so that is the option I chose. But when I went to categorize the credit card transactions, I can
    • Permissions on Views

      Having the option of any agent creating custom views is firing back and got a situation where there are a hundred different views across the team and tickets are not being dealt in the most efficient of ways. Tickets seems to be missed by some agents,
    • Function #8: Add additional charges to invoices

      Here goes one of the highly sought-after custom functions in Zoho Books. If you find yourself needing to apply additional charges to customers on their invoices (say credit card surcharges, or fuel charges applicable to customers from a certain region,
    • VIsual maindmaps in Zoho notebook Ai

      Can I create and export VIsual maindmaps in Zoho notebook Ai
    • 1stDibs Integration to Zoho Inventory

      Hello is it possible to integrate my Zoho inventory and 1stDibs?
    • Community Question: Renewal vs Invoicing

      This is a question for the community. Does anyone else consider there to be a difference between a subscription renewal event and sending out a recurring invoice for a subscription? For example, let's say customer XYZ purchases a 1-year subscription to
    • cloud console support for music websites

      Hi Friends, I am not from a very technical background.. So need support from the Zoho family. I want to build a e-commerce website which is in Musical Niche. It will help people learn music & play instruments of all types. There are a few players in the market like Chordify , Guitaa, Guitar Dashboard, ChordU & few others. But I all these websites allow only a few instruments  to play. So I want to build a better  website than the one I mentioned. So wnated to know what UI & AI should I use so that
    • Scheduled Reports - Do not send empty report

      Hello, We are intensively using reports in the CRM, especially for sales managers. When data is empty, they still receive an email. Can you add an option to avoid sending the report when data is empty?
    • Is Zoho One Desktop more secure than Zoho One Web SaaS?

      Is Zoho One Desktop more secure than using Zoho One in browser? Inherently, it seems desktop would be unless you don't do things like share your pw or leave pc on. I am concerned about data being on the cloud or someone else's server and database.
    • Next Page