Kaizen 254 - Building a Temporal Lead Score Decay System in Zoho CRM

Kaizen 254 - Building a Temporal Lead Score Decay System in Zoho CRM



Hello, CRM Wizards!

Welcome to a fresh week of Kaizen. 

In this post, we will build a temporal lead score decay system that works alongside your existing scoring rules by introducing percentage-based score decay driven solely by customer inactivity

By the end of this tutorial, you will have a Current Intent Score that reflects both customer engagement and its recency, enabling your sales team to prioritize leads with the strongest current buying intent.

Business Problem

Scoring rules evaluate customer activities against configured criteria and adjust scores whenever those conditions are met.

However, once a score is awarded, it generally remains until another qualifying activity changes it or the scoring conditions are evaluated again. This means the score does not naturally lose value simply because the customer has been inactive.

As a result, a lead that accumulated a high engagement score several days ago may continue to appear more valuable than a lead with more recent engagement, even though its current buying intent has declined.

Solution Overview

To address this, we will introduce a percentage-based temporal decay model that gradually reduces a lead’s score based solely on the customer’s inactivity period.
The solution separates engagement scoring from intent scoring.
  1. The Engagement Score continues to represent the customer’s latest engagement based on your configured scoring criteria.
  2. The Current Intent Score is derived from the Engagement Score and gradually decreases over time according to a the decay model whenever no new customer activity occurs.
It consists of four components:

Engagement Score

A custom field, updated by the scoring rule whenever a qualifying customer activity occurs. This represents the customer’s latest engagement score and serves as the base score for calculating temporal decay.

Current Intent Score

A custom field, that stores the score after applying percentage-based temporal decay. This is the score that sales representatives should always use to prioritize leads, as it reflects both the customer’s engagement and the time elapsed since the last qualifying activity.

Workflow 

Whenever the Engagement Score is updated, the workflow immediately copies its value to the Current Intent Score, ensuring that new customer activity instantly refreshes the lead’s current intent. 
It also records the timestamp in the Last Engagement Time custom field, which the scheduled function later uses to calculate the inactivity period for score decay.

Scheduled Function

Runs once every day to identify inactive leads, calculate the inactivity period, apply the quadratic decay formula, and update the Current Intent Score.
The Engagement Score serves as the source score maintained by the scoring rule, while the Current Intent Score serves as the operational score used by the sales team for lead prioritization.

Prerequisites

I. Create the Required Custom Fields

Create the following two custom fields in the Leads module using the Working with Custom Fields help page. 

Field
Data Type
Current Intent Score

String
Last Engagement Time

Date & Time



Make a Get Fields Metadata API to get the API names of these fields or go to Setup > Developer Hub > APIs and SDKs > CRM API > Leads to get the valid API names. 

Store the API names, it will be used later in the scheduled function. 

Notes
Note

The Engagement Score custom field can be created during the scoring rule configuration. This ensures that the field remains non-editable for users and cannot be modified through other actions.

II. Create a Connection

Refer to the Working with Connections help page for a step-by-step guide. 

Go to Setup > Developer Hub > Connections and create a connection for Zoho CRM service with the following two oauth scopes:
  1. ZohoCRM.modules.ALL
  2. ZohoCRM.coql.READ

Step 1 - Configure the Scoring Rule

Create a scoring rule that reflects your business requirements. For detailed instructions, refer to the Configuring Scoring Rules help page.

For this demonstration, we will create a scoring rule with a maximum score of 100.

Navigate to Setup > Automation > Scoring Rules and click the New Scoring Rule button.


Configure the scoring criteria based on your business requirements. 

For this example, we will use customer engagement activities supported by Zoho CRM, including:
  1. Emails: Opens, clicks, replies, and bounces.
  2. Calls: Incoming and outgoing call activities.
  3. Campaigns: Customer interactions with marketing campaigns.
  4. SalesIQ: Website visitor activities and engagement signals.
  5.  Any other customer engagement signals relevant to your sales process.

During the configuration, you will see the following option:
Would you like to add score fields to the records?
Click Yes, proceed.
Enter Engagement Score as the field name and choose Score from the adjacent dropdown.


Step 2 - Configure the Workflow

Next, create a workflow rule that executes whenever the Record Score is updated in the Leads module.

Refer to the Configuring Workflow Rules help page and Setting Field Updates help page for a step-by-step guidance. 

Go to Setup > Automation > Workflow Rules.
Create a workflow for the Leads module and apply it to all records. Under Instant Actions, add two Field Update actions.

Field Update 1: Last Engagement Time

Configure the first field update as follows:
  1. Field: Last Engagement Time
  2. Value to be updated: Static
  3. Select Execution Day from the calendar picker.
This stores the date and time when the Engagement Score was last updated due to customer activity.

Field Update 2: Current Intent Score

Create another field update and configure it as follows:
  1. Field: Current Intent Score
  2. Value to be updated: Reference
  3. Reference Field: Engagement Score
Whenever the Engagement Score changes, the workflow immediately copies its value to the Current Intent Score.


Since sales representatives always use the Current Intent Score to prioritize leads, this ensures that any new customer activity is reflected immediately instead of waiting for the next scheduled execution.
Save the workflow rule.

Step 3 - Create the Scheduled Function

The final step is to create a scheduled function that introduces percentage-based score decay during periods of inactivity.

For detailed instructions, refer to the Creating Schedules in Automation help page. 

Go to Setup > Automation > Schedules and click Create New Schedule

Configure the schedule to run once every day


The scheduled function performs the following operations.

Fetch the Eligible Leads

Execute a COQL query via invokeUrl task to retrieve the following fields such as Lead ID, Engagement Score, Current Intent Score and Last Engagement Time. 

Filter the records using the following criteria:
  1. Last Engagement Time is older than one day.
  2. Current Intent Score is greater than 0.
whereFilter = "Last_Engagement_Time < '" + cutoffDateTimeStr + "' AND (Current_Intent_Score is null OR Current_Intent_Score != '0')";
coqlQuery = "SELECT id, Engagement_Score, Current_Intent_Score, Last_Engagement_Time FROM Leads WHERE (" + whereFilter + ") LIMIT " + pageOffset.toString() + ", 2000";
coqlBody = Map();
coqlBody.put("select_query",coqlQuery);
info coqlBody.toString();
coqlResponse = invokeurl
[
type :POST
parameters:coqlBody.toString()
connection:"zylker_oauth_connection"
];
info coqlResponse;

Since the score decay operates only during inactivity, leads that have already reached a Current Intent Score of 0 do not require further processing. If a qualifying customer activity occurs later, the workflow immediately refreshes the Current Intent Score, making the lead eligible for future decay calculations.

If your organization contains more than 2000 records, paginate through the COQL response until all eligible records have been processed. In Deluge, this can be achieved using the leftpad() string function and pageOffsets.add() method (add()) on a list object together to process large number of records without writing nested loops. 

pageLoopList = "".leftPad(6).replaceAll(" ",",").toList().subList(0,6);
pageOffset = 0;
updateBatch = List();
for each el in pageLoopList
{
//Your code here
}

Info
For more details, find the complete working code in the CRM Kaizen Git Repository.

Calculate the Inactivity Period

For every lead returned by the COQL query, calculate the number of inactive days using the current date and time and the Last Engagement Time field.
You can use the built-in zoho.currentdate system variable to determine the current date.

Apply Percentage-Based Temporal Decay

The score decay is applied solely based on inactivity. No additional customer activity is required for the score to change.

For the demo, we will use a quadratic percentage decay model so that buyer intent decreases rapidly immediately after the last engagement and then tapers off over time.
The remaining score is calculated as:

Quote
remainingFactor = (1 - (inactiveDays / 5))²
Current Intent Score = max(0, Engagement Score × remainingFactor)

Where, inactiveDays is capped at 5 and the score reaches 0 after 5 inactive days.

For an engagement score of 100, the score progression would look like this:

Inactive Days

Remaining Factor

Current Intent Score

0
1.00
100
1
0.64
64
2
0.36
36
3
0.16
16
4
0.04
4
5
0.00
0

Update the Current Intent Score

After calculating the decayed score, use the Update Records API Deluge task to update the Current Intent Score for each lead. 

Notice that the Engagement Score remains untouched. It continues to represent the customer’s latest engagement, while the Current Intent Score represents the customer’s current buying intent after accounting for inactivity.

Let's Test!

Assume a customer performs a qualifying activity that results in an Engagement Score of 60 and triggered the workflow rule.

If no further qualifying activity occurs for the next two days, the scheduled function identifies the lead as inactive, calculates the inactivity period, applies the percentage-based temporal decay model, and updates the Current Intent Score to 22.


If the customer performs another qualifying activity before the next scheduled execution, the workflow immediately synchronizes the Current Intent Score with the latest Engagement Score, and the inactivity-based decay cycle starts again from the new Last Engagement Time.

The Current Intent Score complements your existing engagement scoring by introducing percentage-based temporal decay during periods of inactivity. This provides sales representatives with a score that reflects not only customer engagement, but also how recently that engagement occurred.

Although this example uses a five-day quadratic decay model, you can customize both the decay period and the decay formula to suit your business requirements.

Further Enhancements

The temporal score decay model presented in this demo uses a fixed decay curve for every lead. Depending on your business requirements, you can make the model more dynamic by introducing a decay factor into the calculation.

For example, the remaining factor can be calculated as:
Quote
remainingFactor = (1 - (inactiveDays / 5))² × decayFactor
This decay factor allows you to influence how quickly a lead’s Current Intent Score decays based on additional business context like territory, customer tier, product interest etc,. 

Scenario 1: Prioritize High-Value Leads

You can derive the weight factor from the Annual Revenue field to slow down or accelerate the decay for different categories of leads. For example, 

Annual Revenue

Decay Factor

Result
Less than $100K

0.8
Faster decay

$100K - $500K

1.0
Standard decay

Greater than $500K

1.2
Slower decay

Scenario 2: Decay Based on Lead Status

The Lead Status field can also influence the decay rate. For example, 

Lead Status
Decay Factor
Result
Attempted to Contact

0.8
Faster decay

Not Qualified

0.6
Much faster decay

Contacted
1.0
Standard decay

Pre-qualified

1.2
Slower decay


This enables your sales process to align score decay with the maturity of each lead. Leads that are already progressing through the sales funnel retain their intent score longer, while inactive or lower-priority leads gradually lose priority more quickly.

We hope you find this kaizen helpful.

Have questions or suggestions? Drop them in the comments or write to us at support@zohocrm.com.

On to Better Building!

----------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------
    • Sticky Posts

    • Announcing the new SKILL.md for Zoho CRM and the updated OAS repository!

      We are introducing a new zoho-crm skill to make working with Zoho CRM Developer tools (like APIs, functions, widgets, client scripts, queries etc) easier and faster, with the help of AI in your preferred AI harness like Claude Code, Codex, Cursor, VSCode
    • Kaizen #256 - Build an Arrival Readiness Web Tab in Zoho CRM

      Hi everyone! Welcome back to the Kaizen series! In the post, we discuss a use case in hospitality industry: how an Arrival Readiness web tab widget can be used to let reception staff identify and resolve issues before arrival of guests. Use case In the
    • 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

    Nederlandse Hulpbronnen


      • Recent Topics

      • Delete CRM Portal

        How do I delete portals from my CRM? I created one just to test, it is not in use and is disabled but it's existence is preventing me from marking fields in modules as "required" unless I make it 'read/write' in the portal first. I'd rather just delete
      • Creating new Teams meeting from CRM doesn't enable Team functions in the meeting

        Hi I'm trying to set up the meeting integration and I've seen that when I create a Meeting in the CRM and set the location to Online and the Provider to Teams, and complete the boxes, add a participant etc, whilst the meeting is created in Teams, the
      • Zoho Books | Product updates | July 2026

        Hello users, We’re excited to bring you the latest updates in Zoho Books for July 2026! This month's release introduces Terminal Payments, CMP-08 filing for composition taxpayers, SEPA Credit Transfer support, and Self-Billed Credit Notes and Debit Notes
      • Calendar invites from Contacts not being assigned to Account in CRM

        Hi all It's that time of year again when I try to get calendar and meetings sorted in CRM. I have two way sync enabled. I have the option set to check for customer meeting invitation mail and to add them as meetings. However, whilst those meetings show
      • Kaizen #258 - Getting Started with zoho-crm SKILL.md

        Howdy tech wizards, Welcome to a fresh week of Kaizen. This week, we are taking a look at the zoho-crm SKILL.md, an Agent Skill designed to help AI coding agents work with Zoho CRM’s developer capabilities. What is zoho-crm SKILL.md? The zoho-crm skill
      • Zoho Tables is now live in Australia & New Zealand!

        Hey everyone! We’ve got some great news to share — Zoho Tables is now officially available in the Australian Data Center serving users across Australia and New Zealand regions! Yes, it took us a bit longer to get here, but this version of Zoho Tables
      • Dashboard/Component filter by probability

        Hi all Can I request the ability to add a Component or Dashboard filter for Deal Probability? Would be useful to be able to see data of deals more than 60% probable. Olly
      • Stock (on-hand) Items not updated after using Composite items

        Hi there, I created a Composite item (consist of 3 items). After I created the Composite item, I invoiced it and shipped the items. However the actual stock on hand of the 3items didn't change at all. Have you guys encountered this? Thank you Regards,
      • Is there a way to show contact emails in the Account?

        I know I can see the emails I have sent and received on a Contact detail view, but I want to be able to see all the emails that have been sent and received between all an Accounts Contacts on the Account Detail view. That way when I see the Account detail
      • Important changes for users with Zoho accounts in the UAE and other Data Centers

        What's changing? Previously, the same email address could be used to create separate Zoho accounts in both the UAE data center and another Zoho data center (such as US, EU, IN, AU, JP, CA, SA or SG). With this change, an email address can be associated
      • 👍 Zoho CRM's Notes now gets Reactions and a new look

        Available in SA and JP DCs. Rolling out to other DCs in phases. Hello everyone, Notes help users capture important updates, collaborate with teammates, and maintain context for records. Now with Note Reactions, users can quickly acknowledge updates, express
      • Conditional Layouts On Multi Select Field

        How we can use Conditional Layouts On Multi Select Field field? Please help. Moderation update: Multi-select picklist fields are now supported in Layout Rules. Additionally, Layout Rules is now available in the Professional Edition. These updates have
      • Zoho Marketing Automation WhatsApp Campaign Import Sync for Zoho Analytics

        WhatsApp is a critical channel in modern marketing, yet WhatsApp Campaign metrics from Zoho Marketing Automation currently cannot be natively imported into Zoho Analytics via the default advanced analytics connector. Integrating this into the standard
      • merge the Multiple POs to single PO if Vendor of PO"s --in Zoho Inventory

        HI Merge the Multiple POs to single PO if Vendor of PO"s are Same ----in Zoho inventory Please provide any work around to achive this .
      • Delug script

        I have been looking at auto-update a amount (home currency) field from another module. Zoho native multicurrency was used in the other module (we have 4 here). Custom script was input with no error, but the field was not updated on trigger. Script as
      • Is there a CRM Deluge function available to convert an RTF (rich text field) to plain text (with no formatting tags)?

        I know that we can run reports so that RTF fields can either show as plain text or the text or the text with the formatting fields included (which is wonderful, btw, as it helps me adjust tags when I need to troubleshoot and just see what I need to see
      • 【Zoholics Japan 2026】ITreview 口コミ投稿キャンペーンを実施します!

        ユーザーの皆さま、こんにちは! 2026年9月25日(金)開催の「Zoholics Japan 2026」会場にて、 Zoho CRM・Zoho Workplace・Zoho Mail を対象とした「ITreview 口コミ投稿キャンペーン」を実施します! Zoholics にご来場いただく皆さま、ぜひこの機会に普段お使いの Zoho 製品について、率直なご感想をお聞かせください。 【キャンペーン内容】 対象製品: ・Zoho CRM ・Zoho Workplace ・Zoho Mail キャンペーン実施時間:
      • Contact removed when picking ticket template.

        hi new to Desk rolling out to company, replacing Freshdesk. Is there way to keep the in context contact when selecting a template? When you choose a template you lose the contact!
      • Using IMAP configuration for shared email inboxes

        Our customer service team utilizes shared email boxes to allow multiple people to view and handle incoming customer requests. For example, the customer sends an email to info@xxxx.com and multiple people can view it and handle the request. How can I configure
      • Zoho Tables is now available in Zoho One!

        Hello Zoho One users, We’re excited to announce that Zoho Tables is now included as a part of Zoho One suite! As teams grow, managing projects, approvals, inventories, campaign trackers, and operational workflows across multiple spreadsheets become difficult.
      • Zoho Publish is now available in Zoho One!

        Hello Zoho One users, We’re excited to announce that Zoho Publish is now included as part of the Zoho One suite! As businesses grow, managing Google Business Profiles across many locations becomes challenging. Business information needs to stay accurate,
      • Global Sets for Multi-Select pick lists

        When is this feature coming to Zoho CRM? It would be very useful now we have got used to having it for the normal pick lists.
      • Bank Transaction Rules Link Under Each Bank Account

        Hello, can you'll move the "transaction rules" button or link back under each bank account? It is now on Bank Overview, if I am working on a specific bank account, I don't want to go out to overview to check the rules. That button displays rules for all
      • Nested notebooks

        Dear Sir/Madam, I would like to know if it is possible to nest notebooks. It would be very helpful when there are too many, as it would improve organization. Thank you for your response. Best regards.
      • Zia Agents looks promising, but I still cannot deploy my first agent or connect WhatsApp after weeks of support tickets

        Hi Everyone, I am posting here because I am stuck and need practical help from someone who has successfully deployed a Zia Agent with WhatsApp. Zia Agents looks like a very promising product. I have watched the platform expand quickly, and I have noticed
      • Zoho CRM

        Cuándo voy a adjuntar un archivo .pdf en un registro en el campo Archivo obtengo el siguiente error:
      • Implement Meeting Polls in Zoho Bookings

        Dear Zoho Bookings Support Team, We'd like to propose a feature enhancement related to appointment scheduling within Zoho Bookings. Current Functionality: Zoho Bookings excels at streamlining individual appointment scheduling. Users can set availability
      • Recording Salaries and wages in zoho books with bank fees

        Hello Community, I am posting this questions to understand the best way to record the salary and payroll expenses in zoho books. The way it works here, For example if I have 3 employees and each employee salary is lets say $1000. I usually use the bank
      • API - Available Stock Definitions

        Okay, Zoho team... your copywriters fell down on the job for this one :) I think these warrant a bit more explanation as to what they include and what they don't.
      • [BUG] WebTabs in ZohoCRM now have a spurious "\" displayed along with some additional HTML Head code included

        An example of the issue can be seen below:
      • CNIL - Suivi de Pixel

        Bonjour à tous, À la suite de la nouvelle recommandation de la CNIL sur les pixels de suivi dans les e-mails, savez-vous si Zoho Campaigns permet : de conditionner le suivi des ouvertures au consentement de chaque contact ; de proposer un lien permettant
      • Scheduled import

        The tutorial shows a scheduled import option but this option doesn't appear to be available when using Zoho DB.
      • #4 Choosing How My Invoice Should Look

        Day 4: Meera had the basics sorted. Her business name was there, the address looked right, and her logo finally appeared where it should. But the invoice still did not quite look like hers. Her old studio used invoices that were clean, tightly laid out,
      • Transaction rules for "Owner's Contribution" ?

        I have a bank account where a lot of the deposits are "Owner's Contributions" (i.e., the business owner investing money in the company). Is it possible to create a Transaction Rule to automatically recognize these? They all have the same verbiage from
      • DYK 12: Turn Email into Work Items

        Did you know you can add work items to your Zoho Projects portal directly from your inbox? The initial step of important collaborations start over an email, and most of these require an immediate follow-up by creating a task, or reporting an issue. During
      • Custom Function not getting package details when triggered from Workflow Rules.

        I have a custom function for Packages that submits a form in our Creator app that we use to generate custom shipping labels (internal staff complete deliveries so we cannot generate shipping labels straight from Inventory). When the function is executed
      • how to Solve Conflict Invoices in Zoho POS

        Hello Team, I am facing a repeated issue in Zoho POS while saving a sale that contains service-based items. My products are intentionally created as Service (Non-Inventory) items because I do not want to track stock for them. However, every time I try
      • ¿Cuándo estará disponible la edición de Zoho POS para México?

        He estado revisando las capacidades de Zoho POS y su evolución dentro de la estrategia de Zoho for Retail, y me parece que existe una oportunidad muy interesante para el mercado mexicano. Zoho POS ya ofrece funcionalidades para gestionar ventas, inventario,
      • Important update for Zoho RPA Windows Agent users

        Hi everyone, We would like to share an important update for Zoho RPA Windows Agent users running Windows Server 2016 or Windows Server 2019. The new Zoho RPA Windows Agent 6.0.0 and later versions are not supported on Windows Server 2016 and Windows Server
      • Multi-Option Estimates: One Estimate, Multiple Choices

        Every service request can have multiple solutions. Multi-Option Estimates help you present these different solutions in a single estimate with its own name, parts, price, and total. Each option can differ in scope, approach, or price — whatever choices
      • Next Page