Kaizen 235 - Restore deleted records from the Recycle Bin using Zoho CRM APIs

Kaizen 235 - Restore deleted records from the Recycle Bin using Zoho CRM APIs


Welcome to another Kaizen week.

Here's a question that came up in our developer forum:

"I'm working on a piece of software to automate conversion of Leads into Deals based on order status from my company's website. There are some cases where a previously deleted Deal needs to be restored, such as when a failed order is manually corrected. Recovering a record from the recycle bin manually is trivial, but obviously I'm trying to automate the whole process. Is it possible to recover a record from the recycle bin using the API?"

This is a problem that many developers may have run into when building integrations.

Consider Zylker, a company that syncs orders from their e-commerce platform directly into Zoho CRM as Deals. Their workflow is straightforward: a new order comes in, a Deal is created. An order fails, the Deal gets deleted. Clean and simple.

But real-world workflows rarely stay that simple. Sometimes a failed order gets manually corrected on the e-commerce side. The customer fixes their payment, the warehouse confirms stock, the ops team overrides the rejection. When that happens, Zylker needs to bring that Deal back to life in CRM, complete with all its history, notes, activities, and associations.

The naive solution is to create a new Deal. But that means losing everything that was attached to the original record like call logs, emails, notes, contact role associations. For a sales team, that history is valuable. Creating a duplicate isn't a restore, it's a data integrity problem waiting to happen.

The right solution is to restore the original Deal from the Recycle Bin programmatically. This is the problem we’ll address in this post.

 What the Recycle Bin API offers 

To implement this workflow, we’ll rely on the Recycle Bin APIs available in Zoho CRM.  There are six key endpoints:

 1. Get Recycle Bin records 

Endpoint: GET {api-domain}/crm/v8/settings/recycle_bin

This endpoint fetches all deleted records across modules. In Zylker's case, this is how we search for a deleted Deal before restoring it. The API supports a filters parameter to narrow results based on module, display name, deletion time, or user.

Other supported parameters are:

  • ids - retrieve specific records by their unique IDs. Takes precedence over filters if both are provided

  • sort_by - sort by display_name, deleted_time (default), or deleted_by

  • sort_order - asc or desc

  • page / per_page - paginate through results. Maximum 200 records per page. Check "more_records": true in the response to know if more pages exist

 2. Get a single Recycle Bin record 

Endpoint: GET {api-domain}/crm/v8/settings/recycle_bin/{record_id}

This API fetches details of a specific deleted record by its ID.

This is most useful in integrations where the external system stores the CRM record ID at the time of creation.


NotesThe Recycle Bin API only returns metadata about deleted records, not the full record details. The response contains the record's id, display_name, module, owner, deleted_by, and deleted_time. If you need the full record details, you should restore the record first and then fetch it via the get records API.

 3. Restore Recycle Bin records 

Endpoint: POST {api-domain}/crm/v8/settings/recycle_bin/{record_id}/actions/restore

This API restores a specific deleted record by its ID. When a record is restored, any associated records that are also in the Recycle Bin, such as Notes, Attachments, or Activities, are restored automatically along with it. This is a key advantage over recreating the record from scratch, where all that history would be permanently lost.

Note: Records are only available in the Recycle Bin for 60 days after deletion. After that they are permanently deleted and cannot be restored via API or manually.

 4. Get Recycle Bin record count 

Endpoint : GET {api-domain}/crm/v8/settings/recycle_bin/actions/count

This API returns the total number of records currently present in the Recycle Bin.

For example, Zylker could run a nightly process that checks this endpoint first. If the count is zero, the job exits without making additional API calls.

Monitoring this count can also help detect unexpected spikes in deleted records, which may indicate faulty automation or synchronization issues.

 5. Delete Recycle Bin records 

Endpoints:

DELETE {api-domain}/crm/v8/settings/recycle_bin/{record_ID}

DELETE {api-domain}/crm/v8/settings/recycle_bin?ids={id1,id2,...}

DELETE {api-domain}/crm/v8/settings/recycle_bin?filters={filter_value}

This endpoint permanently deletes one or more records from the Recycle Bin. Unlike a regular delete that moves records to the Recycle Bin, this removes them with no possibility of recovery.

A common use case is compliance-driven data erasure. For example, when a customer requests permanent deletion of their data under regulations like GDPR, the record can first be deleted from its module and then permanently removed from the Recycle Bin.


Notes
When a record is deleted from the Recycle Bin, all its associated records like Notes, Attachments, Activities are also permanently deleted. If the total number of records exceeds 1000, the deletion is scheduled as a background job.

 6. Empty the Recycle Bin   

Endpoint: POST {api-domain}/crm/v8/settings/recycle_bin/actions/empty

This API permanently deletes all records currently present in the Recycle Bin.

This is useful at the end of a bulk data migration or a testing cycle, where large numbers of records have been deleted and need to be permanently purged without going through them individually.

Automating Deal recovery from the Recycle Bin  

Now that we've covered the available Recycle Bin APIs, let's put them to work by building a recovery workflow for Zylker's integration.

Recall that Zylker’s integration creates Deals in CRM whenever a new order is placed. If an order fails, the corresponding Deal may be deleted. Later, if the order is corrected, the integration needs to restore the original Deal so that the sales team can continue working with the same record and retain its associated history.

To automate this process, we can implement a recovery workflow that performs the following steps:

  1. Identify the deleted Deal that needs to be restored.

  2. Retrieve the corresponding record from the Recycle Bin.

  3. Restore the record programmatically.

  4. Perform post-restore updates so the sales team knows the record was recovered.

The function below demonstrates how this can be implemented using Deluge.

The function supports two recovery paths:

  • Direct restoration using a record ID when the integration already knows the Deal ID in CRM.

  • Search-based restoration using the Deal name and a time window, which helps locate the correct record when the ID is not available.

Once the Deal is restored, the function also performs a few post-restore actions:

  • Updates the Deal stage to Needs Analysis

  • Adds a note indicating that the Deal was restored and why

This keeps the sales team informed and preserves a clear activity history.

The function has three parameters:

  1. deal_name (string) - The name or partial name of the Deal to search for

  2. days (integer) - The number of days to look back from the current day

  3. record_id (string) - The CRM record ID of the deleted Deal, if known. 

The record_id parameter is optional. If provided, the function skips the search and restores the record directly. If not, it falls back to searching by deal_name and days. This makes the function flexible enough to handle both scenarios: integrations that track CRM record IDs externally, and those that don't.

Before you begin:

This function uses a Zoho OAuth connection named crm_oauth_connection to make authenticated API calls to the Recycle Bin endpoints internally. Before running the function, set it up as follows:

  1. Go to Setup > Developer Hub > Connections

  2. Click Create Connection

  3. Choose Zoho CRM as the service

  4. Set the connection name to crm_oauth_connection (this must match exactly what is used in the code)

  5. Add the following scopes:

    • ZohoCRM.modules.ALL

    • ZohoCRM.settings.recycle_bin.READ

    • ZohoCRM.settings.recycle_bin.UPDATE

  1. Click Create and Connect and complete the authorization

 

Note: If this connection expires at any point, the function will return an UnAuthenticated Connection error. Go back to the Connections page and reauthorize it to resolve this.


The full implementation of the recovery function is available for download here : restoreDeletedDeal

Let's briefly walk through the logic implemented in the function.

1. The recovery path

The function first determines which recovery path to follow based on whether a record_id is provided.

if(record_id != null && record_id.trim() != "")

If record_id is a non-empty string, the function restores the Deal directly using that ID. This is the most reliable approach because it avoids ambiguity and ensures that the correct record is restored.

If the ID is not provided, the function falls back to searching the Recycle Bin using the Deal name and a configurable time window.

2. Searching the Recycle Bin

When the record ID is unavailable, the function retrieves deleted records and filters them to locate the correct Deal.

The filtering logic ensures that:

  • Only records from the Deals module are considered

  • The Deal name matches the input

  • The record was deleted within the specified time window.

This helps narrow down the correct record and avoid restoring unrelated Deals.

if(moduleApiName == "Deals"

    && displayName.trim().toLowerCase().contains(trimmedName)

&& deletedDate >= lookbackDate)

3. Handling search results

If no matching records are found, the function returns a not found message. If exactly one match is found, its ID and name are stored and the function proceeds to the restore step. If multiple matches are found, the function returns a structured list instead of guessing which one to restore:

if(matchedRecords.size() > 1)

{

    resultMsg = "Multiple Deals found matching '" + deal_name + "'. Please call this function again with the correct record_id:\n";

    for each match in matchedRecords

    {

        resultMsg = resultMsg + "- ID: " + match.get("id")

            + " | Name: " + match.get("deal_name")

            + " | Deleted On: " + match.get("deleted_time")

            + " | Deleted By: " + match.get("deleted_by") + "\n";

    }

    return resultMsg;

}

The caller must review the list, identify the correct record, and call the function again with the record_id directly.

4. Restoring the Record

Once the correct record ID is confirmed, the function calls the Restore endpoint.

restoreResponse = invokeurl

[

    url: "https://www.zohoapis.com/crm/v8/settings/recycle_bin/" + matchedRecordId + "/actions/restore"

    type: POST

    connection: "crm_oauth_connection"

];

The response is checked for two possible success codes - SUCCESS for an immediate restore, and SCHEDULED when the record has more than 1000 associated records and the restore runs as a background job. Both are handled as successful outcomes with different return messages.

5. Post-restore updates

After a successful restore, the function updates the Deal stage and adds a Note:

dealUpdate.put("Stage", "Needs Analysis");

zoho.crm.updateRecord("Deals", matchedRecordId.toLong(), dealUpdate);

noteContent = "Deal restored by " + currentUserName + " on " + currentDate + ". Reason: Order corrected.";

zoho.crm.createRecord("Notes", note);

Both updates are placed after the restore call. If the restore fails, neither runs, keeping the CRM data consistent.

Calling the function via REST API  

One of the powerful capabilities of Zoho CRM is that standalone Deluge functions can be exposed as REST API endpoints and called from any external system. This is what allows Zylker's e-commerce backend to trigger the recovery workflow directly whenever an order is corrected.

Enabling the Function as a REST API  

Once the function is saved, follow these steps to expose it as a REST API:

  1. Go to Setup > Developer Hub > Functions

  2. Click the (three dots) next to the corresponding function (restoreDeletedDeal)

  3. Click REST API

  4. Enable the OAuth2 slider

  5. Copy the endpoint URL shown

  6. Click Save.

The endpoint will be in the following format:

POST https://www.zohoapis.com/crm/v7/functions/{function-name}/actions/execute?auth_type=oauth

While calling the function, arguments must be passed in the request body as a form-data parameter named arguments, with the values as a JSON string.

Sample: {"deal_name":"Zylker","days":10,"record_id":""}

Required scope: ZohoCRM.functions.execute.CREATE

Conclusion  

The Recycle Bin API is a powerful but often overlooked capability in Zoho CRM. As we've seen in Zylker's scenario, restoring deleted records programmatically isn't just a convenience. It is a data integrity requirement for integrations that need to maintain a consistent, unbroken history of records across systems.

We hope this post helps you build more resilient and data-safe integrations on Zoho CRM. If you have questions or want to share how you've used the Recycle Bin API in your own integrations, drop a comment below!

 

 


    • 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

    • The Social Playbook March edition: Myth vs Facts

      We’ve all heard a lot of myths growing up. Some sound convincing, some feel believable, and over time they start to feel like facts. But the truth is, a myth is still a myth until it’s backed by real facts. Marketing is no different. Over time, many ideas
    • Updating Analytical Fields Data

      Dear Zoho team, I'm having an issue with the recently added fields in both Analytical Desk and Analytical. How can I generate the data in Analytical when new fields are added? https://analytics.zoho.com/workspace/2436819000000007005/edit/24368190000
    • Marketing Tip #26: Optimize product images for SEO

      Product images can do more than make your store look good. They can also help customers discover your products through search. Since search engines can’t "see" images, they rely on text signals to understand what an image is about. Two small actions make
    • What's New in Zoho Analytics - February 2026

      Hello Users! We're back with another round of updates for Zoho Analytics. This month's release focuses on giving you greater flexibility in how you visualize, manage, and act on your data - with new features like custom visualizations, remote MCP server,
    • Clone a Module??

      I am giong to repurpose the Vendors module but would like to have a separate but very similar module for another group of contacts called Buyers. I have already repurposed Contacts to Sellers. Is it possible to clone (make a duplicate) module of Vendors
    • [Webinar] Solving business challenges: Secure, real-time, and external collaboration

      Hi Zoho Writer users, We are excited to announce Zoho Writer's webinar for March 2026: Solving business challenges: Secure, real-time, and external collaboration. Zoho Writer supports real-time collaboration by allowing teams to work together in documents.
    • Realtime Translations of Video via OnAir

      It would be an amazing feature to have a drop down selector in the On Air video area for attendees to select a language to convert the original language to.
    • can change deal colors in bigin?

      can be super useful if we can change colors deals process any way to do it?
    • You have reached the maximum limit of bank accounts that can be connected to Zoho Books through token.

      I can no longer connect to my bank account to download transactions into Zoho Books. I egt the error message: "You have reached the maximum limit of bank accounts that can be connected to Zoho Books through token. To connect more accounts, write to us
    • Assign emails to lead

      I have some contacts who refers leads but there is no away to manually assign emails to lead.   
    • Print Sales Orders, Purchase Orders or Invoices from API

      Hello, Is it possible to use the print option that is available in Sales Orders Purchase Orders and Invoices with the API?. I don't see any information in the docs about this. Thanks
    • Push Forms to CRM

      Hello, I created a Form but forgot to integrate to CRM before many of the Forms were filled out. Is it possible to push those entries to CRM or should I just export a CSV then upload to CRM?
    • Layout Adjustment.

      Hello Latha, Hope you are doing well. I wanted to check with you about adjusting the layout columns in the Service Report from the backend, as currently there is no capability for us to customize the layout from our end. Below is the output that I am
    • Invoice emails repeatedly "Bounced back" from perfectly good email address of clients.

      Hi For a couple of months now I am getting tens of invoice email invoices "bounced back" from perfectly sound email addresses when they are sent via Zoho Books. (see attached or an example) (the common theme seems to be that the emails are going to either
    • Newby Questions - Vendors, Customers, and Income vs. Other Income Clarifications

      Q1. For Deposits, there does not seem to be an option for "Income". "Other Income" is an option however. What is the process to add the option to assign a deposit to type "Income"? Q2. In many cases Vendors and Customer are the same. Vendors may purchase
    • yodlee bank fees

      My bank feeds have been pretty much error-free until this recent Yodlee update.  I have configured it as per the information however nothing comes through. It says that bank feeds have been refreshed as of 30th June, 2022. It is the end of the financial
    • Create Item group from a composite Item

      I have applied my mind for hours but cannot figure this out. Can you have a composite item in an item group?. E.g. We bundle different color and size SKU's together as composite items. Also Using composite items as Bill of Materials. We want to create
    • Amazon.in FBA multiple warehouse integration with Zoho Inventory

      My organisation subscribed to Zoho One looking at the opportunity to integrate Amazon.in with Inventory. But during the configuration, we understood the integration has severe limitations when it involves multiple warehouses in the same Organisation.
    • Feature Request - Make Available "Alias Name" Field In Item List View

      Hi Zoho Inventory Team, I have noticed that the "Alias Name" field does not appear on the list of selectable columns in the Customise Columns feature in the Items module. This would be very useful to see for businesses who are using the Alias Name field
    • Feature Request - Option To Hide Default System Fields on Items

      Hi Zoho Inventory Team, As far as I know it is not possible to hid some of the defult system fields on Items, such as UPC, MPN, EAN, ISBN. A good use case is that in many cases ISBN is not relevant and it would be an improved user experience if we could
    • 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
    • Zoho Inventory - Composite Items - Assembly - Single Line Item Quantity of One

      Hi Zoho Inventory Team, Please consider relaxing the system rules which prevent an assembly items from consisting of a single line item and outputting a quantity of 1. A client I'm currently working with sells cosmetics and offers testers of their products
    • Categorize Items with Item Headers

      Hello customers, Did you ever want to classify items based on specific categories to help your customers understand your invoice better? With the new Item Header feature, you can easily categorize items in your invoices and estimates and give them a common title.  Item Headers are available in the Invoices, the Recurring Invoices and the Estimates module. It can be carried forward from estimates to invoices at the time of converting the estimates.  To add an item header: Go to the Estimates, Invoices
    • Zoho Creator Developer Console | Improved Distribution and Lifecycle Management for apps

      Hello everyone, We're excited to introduce new enhancements now in the Zoho Creator Developer Console. These updates strengthen private app distribution through licensing controls and extend environment support across all installed apps, helping teams
    • Zoho Notebook API

      Hi there, I was wondering if you guys are planning to create an API service for this product? Currently, I have developed a custom program based on Evernote's API that allows me to automate my notes. The program completely changes the way notes are taken and makes anyone more productive, combining notes, logging, reminders, tasks and time management. I would love to deploy it on the Zoho Notebook API. In fact, I think this would be the perfect product for Zoho to package and offer as a service/product.
    • 554 5.1.1 – Mail sending blocked for the domain(s): [gmail.com]

      Here's your corrected text: Hello, I hope you are doing well. I was unable to send a message and received the following error: "554 5.1.1 – Mail sending blocked for the domain(s): [gmail.com]" I tried to send and deliver an email but got this error. I
    • Add Reauthentication Option for Zoho Bug Tracker Integration in Zoho Desk

      Hello Zoho Desk Team, We hope you're doing well. We would like to request an enhancement to the Zoho Bug Tracker integration within Zoho Desk. Current Limitation: At the moment, there is no option to reauthenticate the Zoho Bug Tracker integration in
    • Newby Questions

      Q1. The top bar of Zoho Books has a "Search in Banking (/) " field. What is the proper use of this text box? - Searching for Amazon for example has no results but there are transactions. - Is the search case sensitive? - Are regular expressions allowed?
    • Three Zoho Billing Limitations Blocking Standard Subscription Operations

      After working through Zoho Billing support for over a year on these three issues without resolution, we wanted to flag them to the broader community. We are curious whether other businesses are running into the same walls. 1. Cannot Prepone (Move Earlier)
    • Automation #3 - Auto-sync email attachments to tickets

      This is a monthly series where we pick some common use cases that have been either discussed or most asked about in our community and explain how they can be achieved using one of the automation capabilities in Zoho Desk. Most of our customers use email
    • Can't add a sender adress from zoho campaigns

      hi, I need to change the sender address for a campaign.  When i try to add it i get a message to say 'duplicated email address found while adding your sender address'.  This is the first campaign i'm sending so I don't understand why this message is displayed? Thanks Jane 
    • Using a custom single line External ID form as merge fields in templates

      Hey everyone, We're looking to integrate a few external systems better with our Zoho CRM, and we had hoped to use external fields for this purpose. In this case, it would mean being able to use our own inoice system's invoice numbers are a direct id compatible
    • Introducing Workqueue: your all-in-one view to manage daily work

      Hello all, We’re excited to introduce a major productivity boost to your CRM experience: Workqueue, a dynamic, all-in-one workspace that brings every important sales activity, approval, and follow-up right to your fingertips. What is Workqueue? Sales
    • Dashboard target enhancements

      Often individuals in IT are creating dashboards for their sales team. The ability to create a single dashboard that can be used by multiple people is key. A components for a dashboard have the ability to filter by logged in user which is great. However
    • Zoho Campaigns - Feature Request - Re-Send Existing Email Action in Automations/Journeys

      Hi Zoho Campaigns and Zoho Marketing Automation teams, I would like to suggest a feature that would make building and managing complex automations significantly easier. The Feature Introduce a “Re-Send” or “Send Existing Email” action within Automations
    • Can I write a check in Zoho Books with no associated bill?

      This currently does not seem possible, and I have a client that desperately needs this function if I am able to convert them with Quickbooks. Thank you in advance for your reply. 
    • ISO 3166-2 Compliant Country and Regions

      Zoho should consider implementing ISO 3166-2 standards for countries and regions in address dropdowns. It adds a lot of noise in the data when items added programmatically conform to ISO 3166-2 (e.g., TX for Texas, CA for Canada, etc.), but the few items
    • US State abbreviations in Address fields

      In regards to all Address fields within Zoho, Is there a way to change the State field to be the 2 letter abbreviation vs the full spelled out US State name? Example: "Washington" should be WA. I am able to type in the abbreviated state, but it's not
    • Zoho Booking - TIN vs ATIN & ITIN

      Zoho Booking Vendors allows for TAX ID values of SSN, EIN, ATIN an ITIN. There is no option for TIN. What is the method to properly add TIN to the list of taxable values for companies? For reference: Social Security Numbers (SSN) Individual Taxpayer Identification
    • Zoho Books | Product updates | October 2025

      Hello users, We’ve rolled out new features and enhancements in Zoho Books. From iOS 26 updates to viewing reports as charts, explore the updates designed to enhance your bookkeeping experience. Zoho Books Updates for Apple Devices At WWDC 2025, Apple
    • Next Page