Creating product-specific sales Pipelines with Zoho CRM APIs

Creating product-specific sales Pipelines with Zoho CRM APIs

Hello everyone!

Welcome back to another week of Kaizen. In last week's post in the Kaizen series, we discussed how an arrival readiness web tab widget can be used to let reception staff identify and resolve issues before arrival of guests. 

In this post, we will explore a real-world use case for creating and managing Pipelines in Zoho CRM using Zoho CRM APIs.

When a business sells multiple products or services, a single sales process may not work for all of them. A customer buying a new car may need to go through a test drive, price negotiation, and financing. An insurance customer may need a quote and document verification. A customer purchasing a service plan may simply need to select a plan and make a payment. Managing all these processes using a single Deal pipeline can make the sales process complicated for sales teams. You can create and manage pipelines for these business scenarios using the Zoho CRM Pipeline APIs.

Let us see how a company can create product-specific sales pipelines in Zoho CRM when it launches new products or services.

Business scenario

Consider Zylker Motors, a company that sells cars and related services.
It has three major offerings:
  1. New Cars
  2. Insurance
  3. Service Plans

Product

Sales process

New Cars

Enquiry → Test Drive → Price Negotiation → Finance → Closed Won

Insurance

Insurance Requirement → Quote → Document Verification → Policy Issued

Service Plans

Service Requirement → Plan Selection → Payment → Activated



When a new product is launched:
  1. Identify the sales process required for the product.
  2. Retrieve the appropriate Deal layout using the Layouts Metadata API.
  3. Retrieve the available Stage values and their IDs using the Fields Metadata API.
  4. If a required stage does not exist, add it to the existing Stage picklist using the Update Custom Field API.
  5. Create a pipeline for the product using the Create Pipeline API.
  6. Add the required stages to the pipeline in the required order.
  7. Make the new pipeline available for use in the sales process.
Let us walk through this process using Zoho CRM APIs.

Identify the Deal layout

A pipeline is associated with a specific layout in the Deals module. Therefore, the first step is to identify the layout in which the new pipeline needs to be created.
Use the Layouts Metadata API to get the layout ID in the Deals module. 

Sample Request
Request URL: {api-domain}/crm/{version}/settings/layouts?module=Deals
Request Method: GET
Response:

{
    "layouts": [
        .
        .
        .
        {
            "has_more_profiles": false,
            "api_name": "Standard__s",
            "name": "Standard",
            "generated_type": "system",
            "id": "5725767000000091023",
        }
    ]
}

The application can use the layout ID when creating the pipeline.
The Create Pipeline API requires the layout_id parameter because the pipeline is created within a specific Deal layout.

Retrieve the available Stage values

Identify the stages required for the new product's sales process using the Fields Metadata API.

Sample Request

Request URL: {api-domain}/crm/{version}/settings/fields?module=Deals
Request Method: GET
Response:

{
    "fields": [
        {
            "pick_list_values": [
                {
                    "display_value": "Enquiry",
                    "sequence_number": 1,
                    "deal_category": "Open",
                    "reference_value": "Enquiry",
                    "probability": 20,
                    "forecast_category": {
                        "name": "Pipeline",
                        "id": "5725767000000006787"
                    },
                    "id": "5725767000000006803",
                    "forecast_type": "Open",
                    "record_category_value": {
                        "api_name": "Open",
                        "id": "5725767000009510024"
                    },
                    "type": "used"
                },
                {
                    "display_value": "Test Drive",
                    "sequence_number": 2,
                    "deal_category": "Open",
                    "probability": 20,
                    "forecast_category": {
                        "name": "Pipeline",
                        "id": "5725767000000006787"
                    },
                    "id": "5725767000000006804",
                    "type": "used"
                },
                {
                    "display_value": "Price Negotiation",
                    "sequence_number": 3,
                    "deal_category": "Open",
                    "probability": 20,
                    "forecast_category": {
                        "name": "Pipeline",
                        "id": "5725767000000006787"
                    },
                    "id": "5725767000000006805",
                    "type": "used"
                },
                {
                    "display_value": "Finance",
                    "sequence_number": 4,
                    "deal_category": "Open",
                    "probability": 20,
                    "forecast_category": {
                        "name": "Pipeline",
                        "id": "5725767000000006787"
                    },
                    "id": "5725767000000006806",
                    "type": "used"
                },
                ...
            ]
        }
    ]
}

The application can use the IDs of these stages when creating the pipeline.
This is important because the Create Pipeline API requires the unique ID of each stage in the maps array. You can obtain these stage IDs using the Fields Metadata API.

What if a required Stage does not exist?

If the sales process requires stages that are not available in the Stage field, add those stages to the Deals module before creating the pipeline.

Use the Update Custom Field API to add the missing stages to the existing Stage picklist. 

Before adding the new stages, retrieve the existing values of the Stage field using the Fields Metadata API.

In this example, the Deals module already contains stages such as Enquiry, Test Drive, Price Negotiation, Finance, and Closed Won. The new sales processes require additional stages that are not currently available.
To add the new stages using the Update Custom Field API, include both the existing Stage values and the new Stage values in the pick_list_values JSON array.

The existing Stage values must be passed with their existing properties, while each new Stage value must be passed with the properties required to create the option, such as display_value, deal_category, forecast_category, probability, and sequence_number.

The following stages are being added:
  1. Insurance: Insurance Requirement, Quote, Document Verification, Policy Issued.
  2. Service Plans: Service Requirement, Plan Selection, Payment, Activated.
The following input contains the existing Stage values followed by the new Stage values. The existing values are retained as they are, and the new values are added with the required properties.

Sample Request

Request URL: {api-domain}/crm/{version}/settings/fields/{stage_ID}?module=Deals
Request Method: PATCH
Input JSON:

{
    "fields": [
        {
            "pick_list_values": [
                {
                    "display_value": "Enquiry",
                    "sequence_number": 1,
                    "deal_category": "Open",
                    "probability": 10,
                    "forecast_category": {
                        "name": "Pipeline",
                        "id": "5725767000000006787"
                    },
                    "id": "5725767000000006803",
                    "type": "used"
                },
                {
                    "display_value": "Test Drive",
                    "sequence_number": 2,
                    "deal_category": "Open",
                    "probability": 20,
                    "forecast_category": {
                        "name": "Pipeline",
                        "id": "5725767000000006787"
                    },
                    "id": "5725767000000006804",
                    "type": "used"
                },
               ...

                // ... other existing stages ...

                {
                    "display_value": "Insurance Requirement",
                    "deal_category": "Open",
                    "forecast_category": {
                        "name": "Pipeline",
                        "id": "5725767000000006787"
                    },
                    "probability": 50,
                    "sequence_number": 6
                },
                {
                    "display_value": "Quote",
                    "deal_category": "Open",
                    "forecast_category": {
                        "name": "Pipeline",
                        "id": "5725767000000006787"
                    },
                    "probability": 50,
                    "sequence_number": 7
                },
               
            ]
        }
    ]
}



For each stage you add, the following properties are mandatory:
  1. display_value: The name of the stage.
  2. deal_category: The category of the Deal stage, such as Open, Closed Won, or Closed Lost.
  3. forecast_category: The forecast category associated with the stage.
  4. probability: The probability percentage associated with the stage.
  5. sequence_number: The position of the stage in the Stage picklist.
After adding the new Stage values, retrieve the updated Stage field metadata using the Fields Metadata API to obtain their IDs. You can then use these IDs when mapping the stages to their respective pipelines.

Create the product-specific pipeline

At this point, the application has all the information required to create the pipeline:
  1. Deal layout ID
  2. Required Stage IDs
  3. Stage order
Zylker can now create a pipeline for the product using the Create Pipeline API.

Sample Request

Request URL: {api-domain}/crm/v8/settings/pipeline?layout_id=5725767000000091023
Request Method: POST
Input JSON:

{
    "pipeline": [
        {
            "display_value": "New Car Sales",
            "default": true, //The default key specifies whether the pipeline is the default pipeline for the layout. Set default to true to make the pipeline the default.
            "maps": [
                {
                    "sequence_number": 1,
                    "id": "5725767000011437001",
                    "display_value": "Enquiry"
                },
               {
                    "sequence_number": 2,
                    "id": "5725767000011437003",
                    "display_value": "Test Drive"
                }, 
                {
                    "sequence_number": 3,
                    "id": "5725767000011437004",
                    "display_value": "Price Negotiation"
                },
                {
                    "sequence_number": 4,
                    "id": "5725767000011437005",
                    "display_value": "Finance"
                },
                {
                    "sequence_number": 5,
                    "id": "5725767000000006816",
                    "display_value": "Closed Won"
                }
            ]
        }
    ]
}



The maps JSON array defines the stages included in the pipeline, while sequence_number determines the order in which they appear.

The Create Pipeline API requires display_value for the pipeline name and maps for the stages. The stage IDs must be valid IDs obtained from the Fields Metadata API.

Sample Response:
{
  "pipeline": [
    {
      "code": "SUCCESS",
      "details": {
        "id": "5725767000011439001" //The application can store this pipeline ID for future operations.
      },
      "message": "Pipeline created",
      "status": "success"
    }
  ]
}


Create pipelines for other products

Same approach can be used for the other products.

Insurance

Insurance Requirement → Quote → Document Verification → Policy Issued

Service Plans

Service Requirement → Plan Selection → Payment → Activated

Each pipeline now represents a different sales process.

What if the sales process changes?

Sales processes often evolve.
Suppose Zylker discovers that EV customers need a technical battery evaluation before price negotiation.

Existing Process: 

  Enquiry → Test Drive → Price Negotiation → Finance → Closed Won


the updated process becomes:

Enquiry → Test Drive → Battery Evaluation → Price Negotiation → Finance → Closed Won


If Battery Evaluation already exists as a Stage option, the application only needs to update the pipeline. 

Retrieve the pipelines configured in the layout using Get Pipelines in a Layout API

Sample Request

Request URL: {api-domain}/crm/v8/settings/pipeline?layout_id=5725767000000091023
Request Method: GET

Response:

{
    "pipeline": [
        {
            "display_value": "New Car Sales",
            "default": true,
            "maps": [
                {
                    "display_value": "Enquiry",
                    "sequence_number": 1,
                    "forecast_category": {
                        "name": "Pipeline",
                        "id": "5725767000000006787"
                    },
                    "actual_value": "Enquiry",
                    "id": "5725767000011437001",
                    "forecast_type": "Open"
                },
                {
                    "display_value": "Price Negotiation",
                    "sequence_number": 2,
                    "forecast_category": {
                        "name": "Pipeline",
                        "id": "5725767000000006787"
                    },
                    "actual_value": "Price Negotiation",
                    "id": "5725767000011437003",
                    "forecast_type": "Open"
                },
                {
                    "display_value": "Finance",
                    "sequence_number": 3,
                    "forecast_category": {
                        "name": "Pipeline",
                        "id": "5725767000000006787"
                    },
                    "actual_value": "Finance",
                    "id": "5725767000011437004",
                    "forecast_type": "Open"
                },
                {
                    "display_value": "Closed Won",
                    "sequence_number": 4,
                    "forecast_category": {
                        "name": "Closed",
                        "id": "5725767000000006789"
                    },
                    "actual_value": "Closed Won",
                    "id": "5725767000000006815",
                    "forecast_type": "Closed Won"
                }
            ],
            "actual_value": "New Car Sales",
            "id": "5725767000011439001"
        }
    ]
}

The application can then update the existing pipeline using the Update a Pipeline API.

Note: If the new stage does not exist in the Stage picklist, the application must first add it to the Stage field using the Update Custom Fields API and then update the pipeline using the Update a Pipeline API. Use the Get Pipelines in a Layout API to get the pipeline ID.


Update the Pipeline using Update a Pipeline API

Sample Request

Request URL: {api-domain}/crm/v8/settings/pipeline/5725767000011439001?layout_id=5725767000000091023
Request Method: PUT

Input JSON

{
    "pipeline": [
        {
            "maps": [ //mandatory to update the stage details
                {
                    "display_value": "Battery Evaluation",
                    "sequence_number": 2,
                    "id": "5725767000011437002"
                }
            ]
        }
    ]
}

The updated maps JSON array can include the Battery Evaluation stage at the required position. 

Note: If you add a new stage with a sequence_number that is already in use, the new stage is added at that position, and the remaining stages automatically follow the next sequence numbers.

What if a pipeline is no longer required?

What if a pipeline is no longer required?
Sales processes can change over time. For example, Zylker may decide to discontinue the New Car Sales pipeline and replace it with a new Vehicle Sales pipeline.

The existing pipeline might contain:

New Car Sales

Enquiry → Test Drive → Price Negotiation → Finance → Closed Won

The new pipeline could have a revised sales process:

Vehicle Sales

Enquiry → Test Drive → Vehicle Evaluation → Price Negotiation → Finance → Closed Won


If the old pipeline has Deals associated with it, simply deleting the pipeline is not enough. The Deals need to be transferred to the new pipeline, and the stages in the old pipeline need to be mapped to the corresponding stages in the new pipeline.

You can use the Transfer and Delete a Pipeline API for this purpose. The API deletes the old pipeline and transfers its associated Deals to the new pipeline. It also allows you to specify how the stages in the old pipeline should be mapped to stages in the new pipeline. 

Transfer Deals and delete the old pipeline

Sample Request

Request URL: {api-domain}/crm/v8/settings/pipeline/actions/transfer?layout_id=5725767000000091023
Request Method: POST

Use the Get Pipelines in a Layout API to retrieve the Pipeline and the respective stage IDs.

The request requires:
{
    "transfer_pipeline": [
        {
            "pipeline": {
                "from": "5725767000011439001", //Old/Source pipeline → this pipeline will be deleted.
                "to": "5725767000011439002" //New/Destination pipeline → Deals will be transferred here.
            },
            "stages": [ //The stage mapping between the old and new pipelines
                {
                    "from": "5725767000011437001", //stage in the old pipeline.
                    "to": "5725767000011437002" //corresponding stage in the new pipeline.
                }
            ]
        }
    ]
}

Key explanation
  1. transfer_pipeline: The root array that contains the pipeline transfer details.
  2. pipeline: Specifies the source pipeline to be deleted and the destination pipeline to which its Deals will be transferred.
  3. pipeline.from: The ID of the pipeline that you want to delete.
  4. pipeline.to: The ID of the pipeline to which the Deals from the source pipeline will be transferred.
  5. stages: Contains the stage mappings between the source and destination pipelines.
  6. stages.from: The ID of a stage in the pipeline being deleted.
  7. stages.to: The ID of the corresponding stage in the destination pipeline where the Deals should be placed.

Create a Deal with the new pipeline using Insert Records API

Once the New Car Sales pipeline has been created and its stages have been configured, the sales team can create a simple Deal using the pipeline and one of its stages to verify that the configuration works as expected. 
For example, when a customer shows interest in purchasing a car, create a Deal in the Deals module using the Insert Records API.

Sample Request


Request URL: {api-domain}/crm/v8/Deals
Request Method: POST

Input JSON
{
    "data": [
        {
            "Deal_Name": "Car Purchase Enquiry",
            "Pipeline": "New Car Sales",
            "Stage": "Enquiry"
        }
    ]
}
Once the setup is validated, they can add the remaining Deal details based on their business requirements.

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!

Cheers!!!