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

    • On Zoho Flow, Record deleted trigger from Zoho Creator

      On creating flow in Zoho Flow, when we select app Zoho created, it provides 3 trigger options - Record created, Record updated and Record created or updated We need trigger on "Record Delete" as well, We have a use case to fire our system api if record
    • Zoho Flow Switch On Not Working

      I have created a flow which is when the mailbox address received the email that meet the condition will auto fetch the contact, account and finally create the ticket by using Zoho Desk. When I do a test and debug on my flow it work well as what I expect
    • MS Teams Flow Integration Question

      Where can I find the chat ID for the "Post message to chat" target?
    • Zoho Flow - Access denied to recover recording from call module - OpenAI

      Hi, I am trying to build a Flow to recover recoding when a new call is saved in my CRM. I have integrated my CRM with ringcentral and the recordings are saved in the event. Trigger: When new module entry Step 2: Fetch module entry (Zoho CRM says "permission
    • Unable to send price in big commerce from zoho flow.

      I am creating a flow from zoho flow to create a product in zoho inventory and sending this to big commerce. But the problem is like when ever i send the price its getting error. it require decimal format value if i am sending ${trigger.sales_rate} the
    • Not sending mail to new lead in zoho flow

      I have created a flow in zoho flow and triggered an action to send email notification when the new lead is created but even after user entering the mail id the email is not going to them
    • Access query string from incoming webhook URL in Zoho Flow

      I have a fairly straightforward use case, but cannot find anything conclusive on this subject. How can I simply access the query string of the incoming webhook request in Zoho Flow? I am attaching the Deal ID to the end of the request like: https://flow.zoho.com/762439902/flow/webhook/incoming?zapikey=1001.0dec2d7dd15080c464a13925275f0129.448c23ee219c545c89f5a178456cfc8b&isdebug=false&dealID=${Deals.Deal
    • Unable to access my Zoho forms account

      For some days now, I haven't had access to my Zoho Forms account. I keep getting an error that says, "You are an inactive user in your organization" via the mobile app and "You don't have permission to access this organization" via the web. I was removed
    • Identify Unused Deluge Functions in Zoho CRM

      Hello Zoho Support Team, I would like to request a feature that helps administrators identify unused or rarely used Deluge functions in Zoho CRM. Currently, Deluge functions are distributed across different areas, and there is no centralized overview
    • Update on V2 API End-of-Life Timeline

      Dear Users, Earlier this year, we shared the launch of the V3 APIs and requested users to migrate from the older V2 APIs by December 2025. We have received valuable feedback from our users and partners regarding their migration timelines. We are happy
    • Run a workflow after record merge

      Hello, We are wondering if there is a way to trigger a workflow after two records are merged? We have a sms service that use to text back and forth with Prospects and Contacts. To make it easy for our users, we automatically create them in this other
    • Live webinar | The Evolution of Zoho Show: 2025 Feature Recap

      2025 has been a year of exciting updates and features for Zoho Show. From advanced design and formatting tools to smarter presentation delivery, enhanced collaboration, and AI-powered features—along with the launch of our desktop apps, Show has continued
    • Batch Tracking custom function

      Hi fellow zoho users, We have our ecommerce site setup to shopify. I have some products I want to add batch tracking too, my only issue is that it breaks our shopify workflow (create sales order, invoice, payment, package) because it requires us to manually
    • Include Suggested Articles in New Ticket Email

      When someone creates a new ticket, is there any way to include recommended knowledge base articles (like the ones Zia Suggests) in the email notification to the user? When they're waiting for a reply, it would be nice to have sent them some recommended
    • Zoho Flow + QuickBooks Estimates – Line items not created from CRM subform

      Hi everyone, I’m trying to create QuickBooks Estimates from Zoho CRM Quotes using Zoho Flow. I’m aware that Zoho Flow’s native “Create Estimate” action does not support multiple line items, so I followed the community guidance for Invoices using a custom
    • SAP S/4 HANA Integration via ZOHO Flow

      Hi How do I change the SAP Client ID while creating a new connection ? MY client ID is 421. I believe the client id should be an input field for length 3 numbers rather then a drop down to select from a fixed set of values. Thanks
    • VLOOKUP FUNCTION PROBLEM

         Hello, i have a problem with the VLOOKUP  function in my sheet http://public.sheet.zoho.com/public/tonimoreno/indicemasacorporal2 in cell D2. This function doesn't work correctly and always returns the last content of the range. Can you help me?
    • Zoho Flow Completely Broken?

      Since December 13th, 100% of our flows have stopped working completely. Nothing is working or triggering??? I called support & sat on the line with them for 2 HOURS until they finally concluded it was a back-end problem on their end?? Now i'm calling
    • Print / Export full Dashboard page

      Hello Zoho team, It is currently only possible to print/export one component of a dashboard at a time. Requesting the option to print/export a full dashboard page with all components to a pdf or picture. Doing through the browser doesn't give good results.
    • emails duplicated in my outlook client

      Hello I am just new here and I have a litle problem that I do not find how to solve. I sumarise here after. Your help would be very appreciated. I have just recently contracted this zoho mail servicesservices as an initial evaluation yesterday night. I then:   - opened a free account  - created 1 initial email address ..........@domain.com  - created a second email address ..........@domain.com - proceeded with the config instructions (checking the ownership of my domain, changing MX etc... ) as
    • How to check task starting time in zoho mobile app?

      I am using the Zoho mobile app on my iPhone, and I am not able to see the task's starting and finishing times. When opening the Task information / Details, I can only see the Task start date and due date, but not the time. Is there any way to check a
    • Creating an extension in Sigma: Zoho CRM isn't selectable as a service

      I have 2 Zoho accounts which are part of 2 different workplaces. One workplace is able to select 'Zoho CRM' as a service option when creating a new extension, the other one is not. I'm not sure what the exact differences are between them. What do I need
    • List of packaged components and if they are upgradable

      Hello, In reference to the article Components and Packaging in Zoho Vertical Studio, can you provide an overview of what these are. Can you also please provide a list of of components that are considered Packaged and also whether they are Upgradable?
    • Export Tickets from the Help Center

      Hello everyone! We are now allowing end users to export tickets directly from the help center. The ticket export allows users to: Filter tickets by Department, Priority, and Account before exporting. Download files from Export History (Setup > Data administration
    • Is it possible to remove filtering options?

      My CRM has a lot of custom fields that should not be used in filters or views. Fields that are automated and exist only to store temporary values that get used in functions. These create a lot of noise in the list of fields to filter. Isn't there any
    • Function #18: Associate invoice templates automatically based on customer language

      For businesses dealing with a diverse linguistic clientele, it becomes crucial to send out invoices in the customer's preferred language to ensure effective communication. This requirement can be handled in Zoho Books by creating invoice templates in
    • Changing field types

      Question im a Zoho CRM user and curious, if I change a flied type from single or multi line text to a URL field type will i lose the data in the field or will it be converted to website link automatically. Thanks
    • Quote PDF – Header image stopped rendering suddenly

      Hello Zoho Support Team, We are facing an issue with Quote PDF templates in Zoho Books. Previously, images added inside the Quote header HTML were rendering correctly. However, recently the header image is no longer appearing, while header text still
    • Changing Default PDF Name

      Is it possible to change the default name of a PDF? As of right now, all of my quotes are named 'QT_$QuoteNumber' (i,e: 'QT_19803471298374) - would it be possible to change this to: '$CompanyName - $AccountName - $QuoteNumber' for instance?
    • Tip 2: Recursive functions in Deluge: How to dynamically run a function for a specified number of times.

      Hi folks, As part of the Zoho Creator - Tips and Tricks series every fortnight, we are back today with a new tip on Recursive functions.  Let us first quickly understand what Recursive functions are: A function that calls itself one or more times is known as a Recursive function. That is, you can execute a function to perform a particular action a specific number of times. And, at the end of each iteration, a new output is generated. Recursive functions are commonly used by programmers as it enables
    • Function #48: Manage fixed installment payments using Zoho Books

      Hello everyone, and welcome back to our series! Businesses offer installment payment options to their customers, particularly for expensive purchases, to ease the financial burden on them. By breaking down the total cost into smaller, more manageable
    • Spotlight series #6: The Show app for Android TV has a new look!

      Hello everyone! We are delighted to introduce our revamped and redesigned Show app for Android TV.  Smart TVs are exploding in popularity. Android TV alone has over 110 million active monthly devices. Zoho Show, as part of a constant effort to improve
    • Can’t create alias “Email alias already exists”

      Hi, I’m trying to create the following alias for my domain email. contact@ personal@ private@ But I get a email alias already exists. I had a soho account previously which I deleted which I suspect is causing the issue. Can someone assist? Kind Rega
    • Appraisals - Order of Previous Reviews Should Be Newest to Oldest

      The new Zoho People layout generally does a decent job at providing the necessary information for performing appraisals of employee performance. One example of this is the Previous Reviews section: This information is helpful when conducting a review.
    • Paging through API results. a major gap in your documentation.

      There is no way for me. to get all of my data through a single API call. Typically REST APis have mechanisms for paging through API results. But the documentation for the API I am using: https://desk.zoho.com/DeskAPIDocument#Introduction Has no mention
    • Recurring invoices were generated with old template...

      I have recurring invoices setup. Ones generated on 10.20.2025 used the modified template I had used. But for some reason, on the ones created on 11/20/2025, it seems the invoices created reverted to the previous version of the invoice template. Notably,
    • Tip #54- Exploring the Files Icon in Zoho Assist- 'Insider Insights'

      As we’re already in mid-December, it’s a good time to take a closer look at one of the most useful options in the Zoho Assist remote support dashboard—the Files icon. To get started, log in to Zoho Assist using your credentials. Once you’re in, navigate
    • Tip#47: Estimation planner

      Sprint planning becomes easier, smoother, more collaborative and more accurate with the Estimation Planner extension. Most work items involve multiple users, and each user's role and effort vary. To provide an unbiased and fair estimation point to the
    • Time Tracking on Iphone doesn't stop

      When I start a time tracking session the timer starts as expected. However when I hit stop, the timer remains on that project. The only buttons available are discard and start. Start runs the timer more and discard says it will throw away the data from
    • Zoho Sign - Zoho CRM extension upgrade

      Hi everyone, We've updated Zoho Sign extension for Zoho CRM with significant internal changes. Impact on existing Zoho Sign extension users Users using the extension without customization If you are using the integration without implementing Zoho Sign's
    • Next Page