# Java -------------------------------------------------------------------------------- title: "Introduction" description: "Build a Lead Manager application and host it on AppSail. The app connects to your Zoho CRM account using Catalyst connectors, and enables you to view, create, update, or delete leads from the Leads module in your CRM." last_updated: "2026-03-18T07:41:08.683Z" source: "https://docs.catalyst.zoho.com/en/tutorials/leadmanager-appsail/springboot/introduction/" service: "All Services" related: - Project Directory Structure (/en/cli/v1/project-directory-structure/introduction/) - Catalyst SDK for AppSail (/en/serverless/help/appsail/key-concepts/catalyst-configurations/#implementing-catalyst-sdk-in-appsail/) -------------------------------------------------------------------------------- # Lead Manager App Using AppSail ### Introduction This tutorial will help you build a **Java Spring Boot** application web application called **Lead Manager**. This web app will allow you to connect with your {{%link href="https://www.zoho.com/in/crm/" %}}Zoho CRM account{{%/link%}} and enable you to manage leads in your organization. You will be able to access, add, edit, or delete leads in the {{%link href="https://help.zoho.com/portal/en/kb/crm/sales-force-automation/leads"%}}Leads module{{%/link%}} in your CRM account directly from this application. The connection to Zoho CRM is established using {{%link href="/en/api/oauth2/overview-and-terminology/#OverviewandTerminology" %}}OAuth 2.0 authentication protocol{{%/link%}}. We will generate an {{%badge%}}OAuth Access Token{{%/badge%}} for the *Lead Manager* application and use it to authorize the connection to access CRM data. The authentication requirement in this tutorial is handled using {{%link href="/en/cloud-scale/help/authentication/native-catalyst-authentication/embedded-authentication/introduction/" %}}Embedded Authentication{{%/link%}}. We will also implement a {{%link href="/en/sdk/java/v1/connectors/connectors/" %}}Catalyst Connector{{%/link%}} to manage this access to the CRM account. The connector will refresh the {{%badge%}}Access Token{{%/badge%}} automatically each time it expires using a {{%badge%}}Refresh Token{{%/badge%}}, and will maintain a constant connection between the client and the CRM account. These tokens can be generated after registering the client application in the {{%link href="https://api-console.zoho.com/" %}}Zoho API console{{%/link%}} and obtaining the required credentials. The client application will look like this: <br /> The Lead Manager application employs components from the following Catalyst services: - {{%link href="/en/serverless/" %}}**Catalyst Serverless**{{%/link%}}: - {{%link href="/en/serverless/help/appsail/introduction/" %}}AppSail{{%/link%}}: To host the independent *Java Spring Boot* application. We will be building the front-end of the app as well as the back-end logic, and bundling them together to deploy them on AppSail. - {{%link href="/en/cloud-scale/" %}}**Catalyst CloudScale**{{%/link%}}: - {{%link href="/en/cloud-scale/help/data-store/introduction/" %}}Data Store{{%/link%}}: To store the {{%badge%}}Refresh Token{{%/badge%}} and {{%link href="/en/cloud-scale/help/authentication/user-management/users/introduction/" %}}UserID of the Catalyst user{{%/link%}} fetched by the function resource. The {{%badge%}}Refresh Token{{%/badge%}} is fetched from this table by the function, whenever a new {{%badge%}}Access Token{{%/badge%}} needs to be generated. - {{%link href="/en/cloud-scale/help/zcql/introduction/" %}}ZCQL{{%/link%}}: To fetch data from the *Data Store* through querying. - {{%link href="/en/cloud-scale/help/authentication/introduction/" %}}Catalyst Authentication{{%/link%}}: To implement a {{%link href="/en/cloud-scale/help/authentication/social-logins/configuring-social-logins/#enable-zoho-social-login" %}}Zoho social login{{%/link%}} in the client application’s login page, in addition to the standard login option, we will be implementing the {{%link href="/en/cloud-scale/help/authentication/native-catalyst-authentication/embedded-authentication/introduction/" %}}Embedded Authentication type{{%/link%}} in this tutorial. We will use the {{%link href="https://console.catalyst.zoho.com" %}}Catalyst web console{{%/link%}} and the {{%link href="/en/cli/v1/cli-command-reference/" %}}Catalyst Command Line Interface{{%/link%}} (CLI) to build this application. {{%info%}}{{%bold%}}Info:{{%/bold%}} You will be given the code for the files to be included in the function and client components in this tutorial. You will just need to copy the provided code and paste it into the appropriate files as directed.{{%/info%}} ### Application Architecture The Lead Manager application’s architecture is depicted below: <br /> The entire workflow of the application will be explained in more detail when you {{%link href="/en/tutorials/leadmanager-appsail/springboot/code-app" %}}code your front end logic{{%/link%}}, which we recommend you check out as you follow along the steps. -------------------------------------------------------------------------------- title: "Prerequisites" description: "Build a Lead Manager application and host it on AppSail. The app connects to your Zoho CRM account using Catalyst connectors, and enables you to view, create, update, or delete leads from the Leads module in your CRM." last_updated: "2026-03-18T07:41:08.683Z" source: "https://docs.catalyst.zoho.com/en/tutorials/leadmanager-appsail/springboot/prerequisites/" service: "All Services" related: - Catalyst Tools VS Code Plugin (/en/catalyst-extensions/vs-code-extension/introduction/) -------------------------------------------------------------------------------- # Prerequisites Before you begin building the application, you must have the following prerequisites installed on your system: 1. **Catalyst CLI**: Catalyst CLI contains a host of tools that enable you to initialize, develop, test, and deploy the components of your application from your local machine. We will be working with Catalyst CLI in this tutorial. You must perform these actions: - {{%bold%}}Install Catalyst CLI{{%/bold%}}: Catalyst CLI is installed through NPM. You must therefore have NPM and Node.js installed on your system before you install the CLI. Refer to the {{%link href="/en/getting-started/installing-catalyst-cli/" %}}{{%bold%}}Install Catalyst CLI help page{{%/bold%}}{{%/link%}} for details on the pre-requisites and the steps to install it. - {{%bold%}}Login Catalyst CLI{{%/bold%}}: After you install Catalyst CLI, you must authenticate the CLI with your Catalyst account before using it. Refer to the {{%link href="/en/cli/v1/login/login-from-cli/" %}}{{%bold%}}CLI Login help page{{%/bold%}}{{%/link%}} for the steps to login from Catalyst CLI and the various options available for it. 2. **Zoho CRM Account**: Because the Leads module is available in all editions of Zoho CRM, you can have a configured Zoho CRM account of any edition to establish a connection with the Lead Manager application. If you don’t have a Zoho CRM account, you can sign up for it {{%link href="https://www.zoho.com/in/crm/" %}}here{{%/link%}}. 3. **Install Apache Maven Build Automation Tool**: To complete this tutorial, you need to install Maven in your local system. Install the compatible version from your system using this {{%link href="https://maven.apache.org/download.cgi" %}}link{{%/link%}}. 4. **Any IDE tool for Java and client code development** You can use any IDE to work with the function and the client code. Some popular choices include Visual Studio Code, IntelliJ IDEA, Eclipse, and Sublime Text. Download and install an IDE of your choice in your system. {{%info image="/images/tutorials/todo-list/vscode.png"%}}If you are a Visual Studio Code IDE user, you can install the {{%bold%}}Catalyst Tools{{%/bold%}} extension, and use your IDE itself in place of the CLI. You can find more details about the Catalyst VS Code extension from this {{%link href="/en/catalyst-extensions/vs-code-extension/introduction/" %}}help section{{%/link%}}.{{%/info%}} -------------------------------------------------------------------------------- title: "Create a Project" description: "Build a Lead Manager application and host it on AppSail. The app connects to your Zoho CRM account using Catalyst connectors, and enables you to view, create, update, or delete leads from the Leads module in your CRM." last_updated: "2026-03-18T07:41:08.683Z" source: "https://docs.catalyst.zoho.com/en/tutorials/leadmanager-appsail/springboot/create-project/" service: "All Services" related: - Project Directory Structure (/en/cli/v1/project-directory-structure/introduction/) - Catalyst SDK for AppSail (/en/serverless/help/appsail/key-concepts/catalyst-configurations/#implementing-catalyst-sdk-in-appsail/) -------------------------------------------------------------------------------- # Create a Project Let’s {{%link href="/en/getting-started/catalyst-projects/#creating-a-catalyst-project" %}}create a Catalyst project{{%/link%}} from the Catalyst console. 1. Log in to the {{%link href="https://console.catalyst.zoho.com/baas/index" %}}Catalyst console{{%/link%}} and click **Create New Project**. <br /> 2. Enter the project’s name as "**LeadManager**" in the pop-up window. <br /> Your project will be created. You can open the project by clicking **Access Project**. <br /> -------------------------------------------------------------------------------- title: "Create a Table" description: "Build a Lead Manager application and host it on AppSail. The app connects to your Zoho CRM account using Catalyst connectors, and enables you to view, create, update, or delete leads from the Leads module in your CRM." last_updated: "2026-03-18T07:41:08.684Z" source: "https://docs.catalyst.zoho.com/en/tutorials/leadmanager-appsail/springboot/create-table/" service: "All Services" related: - Data Store (/en/cloud-scale/help/data-store/introduction/) - ZCQL (/en/cloud-scale/help/zcql/introduction) -------------------------------------------------------------------------------- # Create a Table Next, let’s create a table in the **Data Store**. This table is used to store the *Refresh Token* and {{%badge%}}userID{{%/badge%}} values, which are retrieved whenever an *Access Token* needs to be generated. To create a table: 1. Navigate to the {{%link href="/en/cloud-scale/" %}}Catalyst Cloud Scale{{%/link%}} service section in the console and click **Start Exploring**. <br /> 2. Click **Create a new Table**. <br /> 3. Enter the table’s name as "{{%badge%}}Token{{%/badge%}}" and click **Create**. <br /> {{%note%}}{{%bold%}}Note:{{%/bold%}} Ensure that you enter the name exactly as instructed because the application's code contains the same name.{{%/note%}} The table will be created. <br /> Now, let’s create two columns in the table to store the {{%badge%}}userID{{%/badge%}} and the {{%badge%}}refresh token{{%/badge%}} respectively. {{%info%}}{{%bold%}}Info:{{%/bold%}} You can learn about the various data types supported by Catalyst and the other properties of a column from the {{%link href="/en/cloud-scale/help/data-store/introduction/" %}}Data Store help documentation{{%/link%}}.{{%/info%}} 4. Click **New Column** in the *Schema View* section. <br /> 5. Enter the column’s name as "refresh_token". Select the data type as Encrypted Text. <br /> 6. Click **Create**. <br /> 7. Now click the **New Column** button again to create the second column. Name it "{{%badge%}}userId{{%/badge%}}", and select **BigInt** as its data type. <br /> 8. Click **Create**. <br /> The required columns have been created. ### Configure Scopes and Permissions To allow any user of the Lead Manager application to view or manage leads from the client application, you must enable an additional {{%link href="/en/cloud-scale/help/data-store/scopes-and-permissions" %}}table permission{{%/link%}} that will allow the user to fetch and store new *Refresh Tokens*, if needed. To enable the required permissions: 1. Click the **Scopes and Permissions** tab. <br /> 2. Enable the **Insert** permission for the **App User** role under the *Table Permissions* section. Ensure you do not change any other permission setting. <br /> The Data Store component is now configured for the application. -------------------------------------------------------------------------------- title: "Enable Zoho Social Login" description: "Build a Lead Manager application and host it on AppSail. The app connects to your Zoho CRM account using Catalyst connectors, and enables you to view, create, update, or delete leads from the Leads module in your CRM." last_updated: "2026-03-18T07:41:08.685Z" source: "https://docs.catalyst.zoho.com/en/tutorials/leadmanager-appsail/springboot/enable-auth/" service: "All Services" related: - Authentication (/en/cloud-scale/help/authentication/introduction/) - Embedded Authentication (/en/cloud-scale/help/authentication/native-catalyst-authentication/embedded-authentication/introduction/) - Enable Social Login (/en/cloud-scale/help/authentication/social-logins/configuring-social-logins/) - Public Sign Up (/en/cloud-scale/help/authentication/public-signup/) -------------------------------------------------------------------------------- # Enable Zoho Social Login Using Embedded Authentication The Lead Manager application contains a login page where you must provide valid credentials to access your Zoho CRM account. You need to implement a signup functionality for this application. The functionality should also provide the option to login to the account using {{%link href="/en/cloud-scale/help/authentication/social-logins/configuring-social-logins/#enable-zoho-social-login" %}}Zoho Social Logins{{%/link%}}. We will be implementing the {{%link href="/en/cloud-scale/help/authentication/native-catalyst-authentication/embedded-authentication/introduction/" %}}Embedded Authentication type{{%/link%}} to complete this requirement. To configure the Zoho social login for the Lead Manager application from the console: 1. Navigate to the **Authentication** component under the *Security & Identity* section, and click **Setup** in the **Native Catalyst Authentication** tab. <br /> 2. Select **Embedded Authentication**, and click **Next**. <br /> 3. You can copy and use the scripts provided in the **Configuration** step to setup your login functionality. However, since we are only going to be using *Zoho social login*, you need to enable the **Public Signup toggle** first. <br /> 4. Click **Yes, Proceed** in the dialog box after going through it. <br /> 5. Click the **Zoho** button to enable the social login. <br /> 6. Provide "{{%badge%}}LeadManagerApp{{%/badge%}}" as the *Client Name* and click **Enable**. <br /> 7. Click **Next**. <br /> 8. We will not be configuring any additional authentication settings for our application. Click **Finish**. <br /> **Embedded Authentication** has been enabled for the application, and users can now login to the app using the **Zoho social login**. <br /> -------------------------------------------------------------------------------- title: "Generate a SpringBoot Project" description: "Build a Lead Manager application and host it on AppSail. The app connects to your Zoho CRM account using Catalyst connectors, and enables you to view, create, update, or delete leads from the Leads module in your CRM." last_updated: "2026-03-18T07:41:08.685Z" source: "https://docs.catalyst.zoho.com/en/tutorials/leadmanager-appsail/springboot/generate-springboot/" service: "All Services" related: - AppSail Help (/en/serverless/help/appsail/introduction/) - AppSail Guide for Spring Boot Apps (/en/serverless/help/appsail/help-guides/java/spring-boot/) -------------------------------------------------------------------------------- # Generate a SpringBoot Project For this tutorial, we are going to create a **Spring Boot - JAR** project using the **Spring Initializr** website. 1. Go to the {{%link href="https://start.spring.io/" %}}Spring Initializr website{{%/link%}}. <br /> 2. Choose or Enter the required details in the following manner: - Select **Maven** as *Project*, **Java** as *Language*, and latest *Spring Boot* version. - Enter "{{%badge%}}**com.catalyst.appsail**{{%/badge%}}" as the *Group*, "{{%badge%}}**leadmanager**{{%/badge%}}" as the *Artifact*, and provide a suitable description. The *Name*, and *Package name* fields will be automatically populated. - Select **Jar** as the *Packaging*, and **17** as the *Java* version. <br /> 3. Click the **ADD DEPENDENCIES** button, on the right side of the screen, and select **Sping Web** in the drop-down and select the dependency. This step will install all the necessary dependencies required to build a Spring Boot web application when you generate the package. <br /> 4. Confirm all your selections, and click **Generate**. <br /> The **leadmanager** Spring Boot project will be downloaded to your local system as a zip file. Unzip the downloaded file and this directory, {{%badge%}}leadmanager/{{%/badge%}} will be our local directory where we initialize the Catalyst AppSail service for our project. Along with all the required dependencies, it will also contain the {{%badge%}}LeadManagerApplication.java{{%/badge%}} file. This file will contain the logic that allows you to run the application on Spring Boot. The {{%badge%}}leadmanager/{{%/badge%}} **Spring Boot - JAR** directory will look like this: <br /> {{%info%}}{{%bold%}}Info:{{%/bold%}} This tutorial has created a {{%bold%}}Spring Boot{{%/bold%}} project to demonstrate building a {{%bold%}}Spring Boot - JAR{{%/bold%}} project, and deploying it as an AppSail service. You can learn how to do the same with {{%bold%}}Spring Boot - WAR{{%/bold%}} projects from this {{%link href="/en/serverless/help/appsail/help-guides/java/spring-boot/#spring-boot---war" %}}help documentation{{%/link%}}.{{%/info%}} For more information on how to create a Spring Boot project, you can visit their official {{%link href="https://spring.io/guides/gs/spring-boot" %}}help documentation{{%/link%}}. -------------------------------------------------------------------------------- title: "Initialize the Project" description: "Build a Lead Manager application and host it on AppSail. The app connects to your Zoho CRM account using Catalyst connectors, and enables you to view, create, update, or delete leads from the Leads module in your CRM." last_updated: "2026-03-18T07:41:08.686Z" source: "https://docs.catalyst.zoho.com/en/tutorials/leadmanager-appsail/springboot/init-project/" service: "All Services" related: - Catalyst CLI (/en/cli/v1/cli-command-reference/) - Initialize Resources (/en/cli/v1/initialize-resources/introduction/) - Catalyst AppSail Help (/en/serverless/help/appsail/introduction/) - Project Directory (/en/cli/v1/project-directory-structure/introduction/) -------------------------------------------------------------------------------- # Initialize the Project You can now begin working on your Catalyst project from the CLI. The first step is to initialize the project in an empty directory. This will be the home directory of your project, and all of the project files will be saved in it. You can learn more about this from the {{%link href="/en/cli/v1/project-directory-structure/introduction/" %}}Project Directory Structure help page{{%/link%}}. You can learn about initializing a project in detail from the {{%link href="/en/cli/v1/initialize-resources/introduction/" %}}CLI help documentation{{%/link%}}. For this application, you will be initializing the {{%link href="/en/serverless/help/appsail/introduction/" %}}AppSail{{%/link%}} component alone. The *AppSail* component will be initialized in the **Node.js** programming stack. 1. Create a folder for the project on your local machine and navigate to it from the terminal. 2. Initialize a project by executing the following command from that directory: {{%cli%}}catalyst init{{%/cli%}} 3. Navigate using the **arrow keys** and select your preferred portal and click **Enter**. If you have no other organizations associated with the account, then the default will be selected automatically. <br /> {{%info%}}{{%bold%}}Info:{{%/bold%}} You can find out more about Catalyst’s multi-org portal feature in this {{%link href="/en/getting-started/catalyst-organizations/#access-the-multi-org-portal" %}}help document{{%/link%}}.{{%/info%}} 4. The CLI will now ask you to associate a Catalyst project with the directory. Associate it with the project that we created earlier from the console. Select **LeadManager** from the list and click **Enter**. <br /> 5. Select **AppSail** using the space bar, then click **Enter** to initialize. <br /> 6. The CLI will prompt you to choose between {{%link href="/en/serverless/help/appsail/catalyst-managed-runtimes/key-concepts/" %}}Catalyst-Managed Runtime{{%/link%}} and {{%link href="/en/serverless/help/appsail/custom-runtimes/container-registry-services/" %}}Docker Image{{%/link%}}. Because you are creating this project from one of the Catalyst-Managed Runtime, select **Catalyst-Managed Runtime** and click **Enter**. <br/> 7. The CLI will initiate the *AppSail* service. - As you are creating your own project, enter "{{%badge%}}n{{%/badge%}}" and click **Enter** for the prompt asking if you wish to get started with a list of recommended projects. <br /> - Enter "{{%badge%}}Y{{%/badge%}}" in the prompt to initialize the *AppSail* service in your current directory. <br /> 8. Enter "{{%badge%}}LeadManagerApp{{%/badge%}}" as the name of your AppSail service, and enter your project directory path as the build path of your AppSail service. <br /> 9. Choose the latest runtime of **Java** as the programming stack, and click **Enter**. <br /> 10. Choose **Java SE** as the platform for your AppSail service. <br /> The AppSail service has been initialized for your Lead Manager application. <br /> The directory will be created in the standard structure, and it will contain the {{%link href="/en/serverless/help/appsail/key-concepts/catalyst-configurations/#the-app-configjson-file" %}}{{%badge%}}app-config.json{{%/badge%}}{{%/link%}} file which includes the configuration of your AppSail service , along with the standard project configuration files such as the {{%link href="/en/cli/v1/project-directory-structure/catalyst-json/" %}}{{%badge%}}catalyst.json{{%/badge%}}{{%/link%}} file and a hidden {{%badge%}}.catalystrc{{%/badge%}} file. This is the structure of the **LeadManager** project’s directory initialized with the *AppSail* service. <br /> ### Deploy the Application You need to deploy the application to the console to fetch the required **application URL**. We need this URL when we register the client in the {{%link href="https://api-console.zoho.com/" %}}Zoho API console{{%/link%}} to get the required {{%badge%}}Client ID{{%/badge%}} and {{%badge%}}Client Secret{{%/badge%}} values. {{%info%}}{{%bold%}}Info:{{%/bold%}} We will be re-deploying the application service once we have completed coding and adding the {{%badge%}}Client ID{{%/badge%}} and {{%badge%}}Client Secret{{%/badge%}} values to the application.{{%/info%}} Enter the following CLI command to deploy the application: {{%cli%}}catalyst deploy{{%/cli%}} Now, to acquire the application URL: 1. Navigate to the {{%link href="/en/serverless/help/appsail/introduction/" %}}AppSail{{%/link%}} component present under the *COMPUTE* section of the **Catalyst Serverless** section of the console. <br /> You will be able to view that your application has been deployed as an AppSail service. 2. Now click your AppSail service, and you will be able to view the application URL. <br /> {{%info%}}{{%bold%}}Info:{{%/bold%}} We will discuss more about the {{%badge%}}catalyst deploy{{%/badge%}} CLI command and the AppSail service, after we re-deploy the application, towards the end of the tutorial.{{%/info%}} -------------------------------------------------------------------------------- title: "Register the Client" description: "Build a Lead Manager application and host it on AppSail. The app connects to your Zoho CRM account using Catalyst connectors, and enables you to view, create, update, or delete leads from the Leads module in your CRM." last_updated: "2026-03-18T07:41:08.693Z" source: "https://docs.catalyst.zoho.com/en/tutorials/leadmanager-appsail/springboot/register-client/" service: "All Services" related: - Catalyst Authentication (/en/cloud-scale/help/authentication/introduction/) - Social Logins (/en/cloud-scale/help/authentication/social-logins/introduction/) -------------------------------------------------------------------------------- # Register the Client We must now register the client application in the {{%link href="https://api-console.zoho.com/" %}}Zoho API console{{%/link%}} to generate the following credentials: - {{%badge%}}**Client ID**{{%/badge%}}: The unique key generated for a registered client - {{%badge%}}**Client Secret**{{%/badge%}}: The secret value generated for a registered client’s {{%badge%}}Client ID{{%/badge%}} The {{%badge%}}Client ID{{%/badge%}} and {{%badge%}}Client Secret{{%/badge%}} are added to the backend and frontend code in several places. These values are necessary to generate the {{%badge%}}{{%bold%}}Access Token{{%/bold%}}{{%/badge%}} and {{%badge%}}{{%bold%}}Refresh Token{{%/bold%}}{{%/badge%}} initially, and later to refresh the {{%badge%}}{{%bold%}}Access Token{{%/bold%}}{{%/badge%}} using the {{%badge%}}{{%bold%}}Refresh Token{{%/bold%}}{{%/badge%}}. To register the client application in the Zoho API console: 1. Visit the {{%link href="https://api-console.zoho.com/" %}}Zoho API Console{{%/link%}} and click **Get Started**. <br /> 2. Select **Server-based Applications** as the client type. <br /> 3. Enter "{{%badge%}}LeadManagerApp"{{%/badge%}} as the **Client Name**. <br /> 4. Provide the other details in the following format: - Homepage URL: **AppSail application URL** - Authorized Redirect URIs: **AppSail applicationURL/generateToken** <br /> Replace {**AppSail applicationURL**} with the application URL you acquired when you deployed your project earlier in this {{%link href="/en/tutorials/leadmanager-appsail/springboot/init-project/#deploy-the-application" %}}step{{%/link%}}. 5. You will need to add another **Authorized Redirect URI** for the client. We will serve the app through a **localhost** to test it after configuring the code. Because this will be redirected to a local domain, we must add that as another authorized redirect URI. <br /> {{%info%}}{{%bold%}}Info:{{%/bold%}} When you serve an application locally from the CLI, it is hosted from {{%badge%}}port 3000{{%/badge%}} by default, unless the port is otherwise occupied. So ensure you are adding the domain accordingly.{{%/info%}} 6. Click **Create**. <br /> The API console will generate and display the {{%badge%}}Client ID{{%/badge%}} and {{%badge%}}Client Secret{{%/badge%}} values for the registered client. You will need to copy these values and paste them into the frontend and backend code of your application. We will discuss this in the following sections. -------------------------------------------------------------------------------- title: "Code Your Application" description: "Build a Lead Manager application and host it on AppSail. The app connects to your Zoho CRM account using Catalyst connectors, and enables you to view, create, update, or delete leads from the Leads module in your CRM." last_updated: "2026-03-18T07:41:08.693Z" source: "https://docs.catalyst.zoho.com/en/tutorials/leadmanager-appsail/springboot/code-app/" service: "All Services" related: - Web SDK for Authentication (/en/sdk/web/v4/cloud-scale/authentication/get-auth-instance/) -------------------------------------------------------------------------------- # Code Your Application In the {{%badge%}}leadmanager/src/main/java/com/catalyst/appsail/leadmanager/{{%/badge%}} directory, create a Java code file and name it {{%badge%}}**LeadmanagerApplication.java**{{%/badge%}}. This code file will contain the logic that will allow you to serve your application. Along with this file, you need to create the following code files in the same directory: * {{%badge%}}**LeadManager.java**{{%/badge%}}: Will contain the business logic of your application. * {{%badge%}}**AuthProviderImpl.java**{{%/badge%}}: Will contain the logic to initialize the {{%link href="/en/sdk/java/v1/overview/" %}}Catalyst SDK{{%/link%}}. In the {{%badge%}}/src/main/resources/static{{%/badge%}} directory, create the following files: * {{%badge%}}**index.html**{{%/badge%}}: The file that contains the HTML code for the front-end of the application. * {{%badge%}}**login.html**{{%/badge%}}: The file that contains the HTML code for the {{%link href="/en/cloud-scale/help/authentication/native-catalyst-authentication/embedded-authentication/introduction/" %}}Embedded Authentication{{%/link%}} logic. * {{%badge%}}**main.css**{{%/badge%}}: The file that contains the styling elements of the application. * {{%badge%}}**main.js**{{%/badge%}}: The file that contains the JavaScript code that connects the front-end and backend. The final structure of the {{%badge%}}leadmanager/{{%/badge%}} **Spring Boot - JAR** project directory is shown below: <br /> You will be coding the {{%badge%}}LeadManager.java{{%/badge%}}, {{%badge%}}LeadmanagerApplication.java{{%/badge%}}, {{%badge%}}AuthProviderImpl.java{{%/badge%}}, {{%badge%}}index.html{{%/badge%}}, {{%badge%}}login.html{{%/badge%}}, {{%badge%}}main.css{{%/badge%}}, {{%badge%}}main.js{{%/badge%}}, and {{%badge%}}pom.xml{{%/badge%}} files. {{%note%}}{{%bold%}}Note:{{%/bold%}} Please go through the code in this section to make sure you fully understand it.{{%/note%}} Copy the code below and paste it into the respective files of your project using an IDE and save the files. {{%panel_with_adjustment class="language-java line-numbers" header="LeadmanagerApplication.java" footer="button" scroll="set-scroll" %}}package com.catalyst.appsail.leadmanager; import java.util.Collections; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import jakarta.servlet.http.HttpServlet; @SpringBootApplication public class LeadmanagerApplication extends HttpServlet { public static void main(String[] args) { String port = System.getenv().getOrDefault("X_ZOHO_CATALYST_LISTEN_PORT","3000"); SpringApplication app = new SpringApplication(LeadmanagerApplication.class); app.setDefaultProperties(Collections.singletonMap("server.port",port)); app.run(args); } } {{%/panel_with_adjustment%}} {{%panel_with_adjustment class="language-java line-numbers" header="LeadManager.java" footer="button" scroll="set-scroll" %}}package com.catalyst.appsail.leadmanager; import java.util.*; import java.util.logging.Logger; import com.zc.auth.CatalystSDK; import com.zc.auth.connectors.ZCConnection; import com.zc.component.ZCUserDetail; import com.zc.component.object.ZCObject; import com.zc.component.object.ZCRowObject; import com.zc.component.object.ZCTable; import com.zc.component.users.ZCUser; import com.zc.component.zcql.ZCQL; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import okhttp3.HttpUrl; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @RestController class LeadManager { @SuppressWarnings("unused") private static final Logger LOGGER = Logger.getLogger(LeadManager.class.getName()); private String apiUrl = "https://www.zohoapis.com/crm/v2/Leads"; private String GET = "GET"; private String POST = "POST"; private String PUT = "PUT"; private String DELETE = "DELETE"; private String CLIENT_ID = ""; //Add your client ID private String CLIENT_SECRET = ""; //Add your client secret OkHttpClient client = new OkHttpClient(); String responseData = ""; MediaType mediaType = MediaType.parse("application/json"); org.json.simple.JSONArray reqData = new org.json.simple.JSONArray(); JSONObject data = new JSONObject(); JSONParser jsonParser = new JSONParser(); @GetMapping("/generateToken") public void generateToken(HttpServletRequest request, HttpServletResponse response) throws Exception { CatalystSDK.init(new AuthProviderImpl((HttpServletRequest) request)); String code = request.getParameter("code"); String domain = (request.getHeader("host").contains("localhost") ? ("http://" + request.getHeader("host")) : ("https://") + request.getHeader("host").split(":")[0]); ZCUserDetail details = ZCUser.getInstance().getCurrentUser(); ZCObject object = ZCObject.getInstance(); ZCRowObject row = ZCRowObject.getInstance(); row.set("refresh_token", getRefreshToken(code, domain)); row.set("userId", details.getUserId()); ZCTable tab = object.getTable(********l); //Replace this with the Table ID of your table tab.insertRow(row); response.setStatus(HttpServletResponse.SC_OK); response.sendRedirect(domain + "/index.html"); } public String getRefreshToken(String code, String domain) throws Exception { HttpUrl.Builder urlBuilder = HttpUrl.parse("https://accounts.zoho.com/oauth/v2/token").newBuilder(); urlBuilder.addQueryParameter("code", code); urlBuilder.addQueryParameter("client_id", CLIENT_ID); urlBuilder.addQueryParameter("client_secret", CLIENT_SECRET); urlBuilder.addQueryParameter("grant_type", "authorization_code"); urlBuilder.addQueryParameter("redirect_uri", domain + "/generateToken"); String URL = urlBuilder.build().toString(); MediaType mediaType = MediaType.parse("text/plain"); okhttp3.RequestBody body = okhttp3.RequestBody.create(mediaType, ""); Request getResponse = new Request.Builder().url(URL).method(POST, body).build(); JSONParser jsonParser = new JSONParser(); JSONObject data = (JSONObject) jsonParser.parse(client.newCall(getResponse).execute().body().string()); return data.get("refresh_token").toString(); } @SuppressWarnings("unchecked") @GetMapping("/getUserDetails") public void getUserDetails(HttpServletRequest request, HttpServletResponse response) throws Exception { CatalystSDK.init(new AuthProviderImpl((HttpServletRequest) request)); Long userId = ZCUser.getInstance().getCurrentUser().getUserId(); String query = "SELECT * FROM Token where UserId="+userId; ArrayList&lt;ZCRowObject&gt; rowList = ZCQL.getInstance().executeQuery(query); JSONObject resp = new JSONObject(); if (rowList.isEmpty()) { resp.put("userId", null); response.setContentType("application/json"); response.getWriter().write(resp.toJSONString()); response.setStatus(200); } else { resp.put("userId", rowList.get(0).get("Token", "userId")); response.setContentType("application/json"); response.getWriter().write(resp.toJSONString()); response.setStatus(200); } } public ArrayList&lt;ZCRowObject&gt; getuserDetails(HttpServletRequest request) throws Exception { CatalystSDK.init(new AuthProviderImpl((HttpServletRequest) request)); Long userId = ZCUser.getInstance().getCurrentUser().getUserId(); String query = "SELECT * FROM Token where UserId="+userId; ArrayList&lt;ZCRowObject&gt; rowList = ZCQL.getInstance().executeQuery(query); return rowList; } @GetMapping("/crmData") public void getAllLeads(HttpServletRequest request,HttpServletResponse response) throws Exception { responseData = getResponse(GET, null,request,apiUrl); response.setContentType("application/json"); response.getWriter().write(responseData); response.setStatus(200); } @GetMapping("/crmData/{id}") public void getLead(@PathVariable Long id,HttpServletRequest request,HttpServletResponse response) throws Exception { String apiUri = apiUrl + "/" + id; responseData = getResponse(GET, null,request,apiUri); response.setContentType("application/json"); response.getWriter().write(responseData); response.setStatus(200); } @SuppressWarnings("unchecked") @PostMapping("/crmData") public void addLead(@RequestBody String leadData,HttpServletRequest request,HttpServletResponse response) throws Exception { JSONObject jsonObject = (JSONObject)jsonParser.parse(leadData); reqData.add(jsonObject); data.put("data", reqData); okhttp3.RequestBody body = okhttp3.RequestBody.create(mediaType,data.toString()); responseData = getResponse(POST, body,request,apiUrl); response.setContentType("application/json"); response.getWriter().write(responseData); response.setStatus(200); } @DeleteMapping("/crmData/{id}") public void deleteLead(@PathVariable Long id,HttpServletRequest request,HttpServletResponse response) throws Exception { String apiUri = apiUrl + "/" + id; responseData = getResponse(DELETE, null,request,apiUri); response.setContentType("application/json"); response.getWriter().write(responseData); response.setStatus(200); } @SuppressWarnings("unchecked") @PutMapping("/crmData/{id}") public void editLead(@PathVariable Long id, @RequestBody String leadData,HttpServletRequest request,HttpServletResponse response) throws Exception { String apiUri = apiUrl + "/" + id; JSONObject jsonObject = (JSONObject)jsonParser.parse(leadData); reqData.add(jsonObject); data.put("data", reqData); okhttp3.RequestBody body = okhttp3.RequestBody.create(mediaType,data.toString()); responseData = getResponse(PUT, body,request,apiUri); reqData.remove(jsonObject); response.setContentType("application/json"); response.getWriter().write(responseData); response.setStatus(200); } public String getResponse(String METHOD, okhttp3.RequestBody body,HttpServletRequest request,String apiUrl) throws Exception { CatalystSDK.init(new AuthProviderImpl((HttpServletRequest) request)); Long userId = ZCUser.getInstance().getCurrentUser().getUserId(); String accessToken = getAccessToken(userId,request); Request getResponse = new Request.Builder().url(apiUrl).method(METHOD, body) .addHeader("Authorization", "Zoho-oauthtoken " + accessToken).build(); String resp = client.newCall(getResponse).execute().body().string(); return resp; } @SuppressWarnings("unchecked") public String getAccessToken(Long userId,HttpServletRequest request) throws Exception { CatalystSDK.init(new AuthProviderImpl((HttpServletRequest) request)); JSONObject authJson = new JSONObject(); JSONObject connectorJson = new JSONObject(); String query = "SELECT refresh_token FROM Token where UserId="+userId; ArrayList&lt;ZCRowObject&gt; rowList = ZCQL.getInstance().executeQuery(query); authJson.put("client_id", CLIENT_ID); authJson.put("client_secret", CLIENT_SECRET); authJson.put("auth_url", "https://accounts.zoho.com/oauth/v2/token"); authJson.put("refresh_url", "https://accounts.zoho.com/oauth/v2/token"); authJson.put("refresh_token", rowList.get(0).get("Token", "refresh_token")); connectorJson.put(userId.toString(), authJson); return ZCConnection.getInstance(connectorJson).getConnector(userId.toString()).getAccessToken(); } } {{%/panel_with_adjustment%}} {{%note%}}{{%bold%}}Note:{{%/bold%}}<br /> * Ensure you add the {{%badge%}}Client ID{{%/badge%}} and {{%badge%}}Client Secret{{%/badge%}} values obtained after you registered the client in the Zoho API console to the lines {{%bold%}}46{{%/bold%}} and {{%bold%}}47{{%/bold%}} respectively, in the above code file. * Add the {{%badge%}}Table ID{{%/badge%}} of the table you created in the {{%italics%}}Data Store{{%/italics%}} in line {{%bold%}}65{{%/bold%}}.{{%/note%}} {{%panel_with_adjustment class="language-java line-numbers" header="AuthProviderImpl.java" footer="button" scroll="set-scroll" %}}package com.catalyst.appsail.leadmanager; import com.zc.auth.AuthHeaderProvider; import jakarta.servlet.http.HttpServletRequest; public class AuthProviderImpl implements AuthHeaderProvider { private HttpServletRequest request; AuthProviderImpl(HttpServletRequest request) { this.request = request; } @Override public String getHeaderValue(String s) { return request.getHeader(s); } } {{%/panel_with_adjustment%}} {{%panel_with_adjustment class="language-xml line-numbers" header="index.html" footer="button" scroll="set-scroll" %}}&lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;meta charset="utf-8" /&gt; &lt;meta http-equiv="X-UA-Compatible" content="IE=edge"&gt; &lt;title&gt;CRM Lead Manager&lt;/title&gt; &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt; &lt;link rel="stylesheet" type="text/css" media="screen" href="main.css" /&gt; &lt;link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"&gt; &lt;link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet"&gt; &lt;link href="https://cdnjs.cloudflare.com/ajax/libs/mdbootstrap/4.19.1/css/mdb.min.css" rel="stylesheet"&gt; &lt;script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"&gt; &lt;/script&gt; &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"&gt; &lt;/script&gt; &lt;script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"&gt; &lt;/script&gt; &lt;script src="main.js"&gt; &lt;/script&gt; &lt;script src="https://static.zohocdn.com/catalyst/sdk/js/4.4.0/catalystWebSDK.js"&gt; &lt;/script&gt; &lt;script src="/__catalyst/sdk/init.js"&gt; &lt;/script&gt; &lt;link href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"&gt; &lt;style&gt; #connect { height: 260px; width: 500px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; margin: auto; } &lt;/style&gt; &lt;/head&gt; &lt;body onload="getUserDetails()"&gt; &lt;br&gt; &lt;center&gt; &lt;h1&gt;CRM Lead Manager&lt;/h1&gt; &lt;br&gt; &lt;/center&gt; &lt;div id="connect"&gt; &lt;center&gt; &lt;p&gt;Click here to connect to Zoho CRM&lt;/p&gt; &lt;button onclick='navigate()'&gt; &lt;img src="https://www.zohowebstatic.com/sites/default/files/styles/product-home-page/public/icon-crm_blue.png" style="width: 180px;height: 130px;"&gt; &lt;/button&gt; &lt;/center&gt; &lt;/div&gt; &lt;div style="width: 200px;float: right; margin-right: 30px;"&gt; &lt;label for="logoutbtn" class="btn btn-success btn-block btn-outlined"&gt;Logout&lt;/label&gt; &lt;button id="logoutbtn" onclick="logout()" style="display: none;"&gt; &lt;/button&gt; &lt;/div&gt; &lt;div id="main"&gt; &lt;div class="container"&gt; &lt;ul class="nav nav-tabs nav-justified mb-3" id="myTab" role="tablist"&gt; &lt;li class="nav-item"&gt; &lt;a class="nav-link active" id="check-tab" data-toggle="tab" href="#check" role="tab" aria-controls="check" aria-selected="true"&gt;Add a Lead&lt;/a&gt; &lt;/li&gt; &lt;li class="nav-item"&gt; &lt;a class="nav-link" id="report-tab" data-toggle="tab" href="#report" onclick="getLeads()" role="tab" aria-controls="report" aria-selected="false"&gt;Manage Leads&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt; &lt;br&gt; &lt;div class="tab-content" id="myTabContent"&gt; &lt;div class="tab-pane fade show active" id="check" role="tabpanel" aria-labelledby="check-tab"&gt; &lt;div class="tab-pane fade show active" id="ex3-tabs-1" role="tabpanel" aria-labelledby="ex3-tab-1"&gt; &lt;div style="margin-left: 100px; margin-right:100px;"&gt; &lt;form id="leads"&gt; &lt;!-- 2 column grid layout with text inputs for the first and last names --&gt; &lt;div class="row mb-4"&gt; &lt;div class="col"&gt; &lt;div class="form-outline"&gt; &lt;label class="form-label" for="form6Example1"&gt;First name&lt;/label&gt; &lt;input type="text" id="firstName" class="form-control" /&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="col"&gt; &lt;div class="form-outline"&gt; &lt;label class="form-label" for="form6Example2"&gt;Last name&lt;/label&gt; &lt;input type="text" id="lastName" class="form-control" required /&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;!-- Text input --&gt; &lt;div class="form-outline mb-4"&gt; &lt;label class="form-label" for="form6Example3"&gt;Company name&lt;/label&gt; &lt;input type="text" id="companyName" class="form-control" /&gt; &lt;/div&gt; &lt;!-- Email input --&gt; &lt;div class="form-outline mb-4"&gt; &lt;label class="form-label" for="form6Example5"&gt;Email&lt;/label&gt; &lt;input type="email" id="email" class="form-control" /&gt; &lt;/div&gt; &lt;!-- Text input --&gt; &lt;div class="form-outline mb-4"&gt; &lt;label class="form-label" for="form6Example4"&gt;State&lt;/label&gt; &lt;input type="text" id="state" class="form-control" /&gt; &lt;/div&gt; &lt;!-- Number input --&gt; &lt;div class="form-outline mb-4"&gt; &lt;label class="form-label" for="form6Example6"&gt;Phone&lt;/label&gt; &lt;input type="number" id="phone" class="form-control" /&gt; &lt;/div&gt; &lt;!-- Number input --&gt; &lt;div class="form-outline mb-4"&gt; &lt;label class="form-label" for="form6Example6"&gt;Lead Source&lt;/label&gt; &lt;input type="text" id="leadSource" class="form-control" /&gt; &lt;/div&gt; &lt;!-- Submit button --&gt; &lt;center&gt; &lt;button type="submit" onclick="createLead();return false;" class="btn btn-primary btn-block mb-4" style="width: 100px;"&gt;Add Lead&lt;/button&gt; &lt;div id="loader" style="display: none;"&gt; &lt;div class="spinner-border" role="status"&gt; &lt;span class="sr-only"&gt;Loading...&lt;/span&gt; &lt;/div&gt; &lt;/div&gt; &lt;/center&gt; &lt;/form&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="tab-pane fade" id="report" role="tabpanel" aria-labelledby="report-tab"&gt; &lt;center&gt; &lt;div id="loaders" style="display: none; padding-top: 200px;"&gt; &lt;div class="spinner-border" role="status"&gt; &lt;span class="sr-only"&gt;Loading...&lt;/span&gt; &lt;/div&gt; &lt;/div&gt; &lt;/center&gt; &lt;p id="showData"&gt; &lt;/p&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;!-- Modal --&gt; &lt;div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"&gt; &lt;div class="vertical-alignment-helper"&gt; &lt;div class="modal-dialog vertical-align-center"&gt; &lt;div class="modal-content"&gt; &lt;center&gt; &lt;h4 class="modal-title" id="myModalLabel"&gt; &lt;/h4&gt; &lt;div class="modal-body" id="message"&gt; &lt;/div&gt; &lt;div class="modal-footer"&gt; &lt;button type="button" style="background-color: #007bff;color: white;" class="btn btn-default" data-dismiss="modal"&gt;Close&lt;/button&gt; &lt;/div&gt; &lt;/center&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="modal fade" id="editForm" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"&gt; &lt;div class="vertical-alignment-helper"&gt; &lt;div class="modal-dialog vertical-align-center"&gt; &lt;div class="modal-content"&gt; &lt;div style="margin-left: 80px; margin-right:80px;"&gt; &lt;br&gt; &lt;center&gt; &lt;h2&gt;Edit Lead&lt;/h2&gt; &lt;/center&gt; &lt;br&gt; &lt;form id="editLeads"&gt; &lt;!-- 2 column grid layout with text inputs for the first and last names --&gt; &lt;div class="row mb-4"&gt; &lt;div class="col"&gt; &lt;div class="form-outline"&gt; &lt;label class="form-label" for="form6Example1"&gt;First name&lt;/label&gt; &lt;input type="text" id="editfirstName" class="form-control" /&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="col"&gt; &lt;div class="form-outline"&gt; &lt;label class="form-label" for="form6Example2"&gt;Last name&lt;/label&gt; &lt;input type="text" id="editlastName" class="form-control" required /&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;!-- Text input --&gt; &lt;div class="form-outline mb-4"&gt; &lt;label class="form-label" for="form6Example3"&gt;Company name&lt;/label&gt; &lt;input type="text" id="editcompanyName" class="form-control" /&gt; &lt;/div&gt; &lt;!-- Email input --&gt; &lt;div class="form-outline mb-4"&gt; &lt;label class="form-label" for="form6Example5"&gt;Email&lt;/label&gt; &lt;input type="email" id="editemail" class="form-control" /&gt; &lt;/div&gt; &lt;!-- Text input --&gt; &lt;div class="form-outline mb-4"&gt; &lt;label class="form-label" for="form6Example4"&gt;State&lt;/label&gt; &lt;input type="text" id="editstate" class="form-control" /&gt; &lt;/div&gt; &lt;!-- Number input --&gt; &lt;div class="form-outline mb-4"&gt; &lt;label class="form-label" for="form6Example6"&gt;Phone&lt;/label&gt; &lt;input type="number" id="editphone" class="form-control" /&gt; &lt;/div&gt; &lt;!-- Submit button --&gt; &lt;center&gt; &lt;button type="submit" id="editBtn" onclick="editLead();return false;" class="btn btn-primary btn-block mb-4" style="width: 100px;"&gt;Edit&lt;/button&gt; &lt;div id="loader" style="display: none;"&gt; &lt;div class="spinner-border" role="status"&gt; &lt;span class="sr-only"&gt;Loading...&lt;/span&gt; &lt;/div&gt; &lt;/div&gt; &lt;/center&gt; &lt;/form&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="modal fade right" id="ModalDanger" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"&gt; &lt;div class="modal-dialog modal-notify modal-danger modal-side modal-top-right" role="document"&gt; &lt;!--Content--&gt; &lt;div class="modal-content"&gt; &lt;!--Header--&gt; &lt;div class="modal-header"&gt; &lt;p class="heading"&gt;Lead Deletion&lt;/p&gt; &lt;button type="button" class="close" data-dismiss="modal" aria-label="Close"&gt; &lt;span aria-hidden="true" class="white-text"&gt;×&lt;/span&gt; &lt;/button&gt; &lt;/div&gt; &lt;!--Body--&gt; &lt;div class="modal-body"&gt; &lt;div class="row"&gt; &lt;div class="col-9"&gt; &lt;p&gt;Are you sure you want to delete the Lead?&lt;/p&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;!--Footer--&gt; &lt;div class="modal-footer justify-content-center"&gt; &lt;a type="button" class="btn btn-danger" id="delete-btn" onclick="deleteLead()"&gt;Delete&lt;/a&gt; &lt;a type="button" class="btn btn-outline-danger waves-effect" data-dismiss="modal"&gt;Cancel&lt;/a&gt; &lt;/div&gt; &lt;/div&gt; &lt;!--/.Content--&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;/body&gt; &lt;script&gt; //Add Your Client ID function navigate() { window.location.href = "https://accounts.zoho.com/oauth/v2/auth?scope=ZohoCRM.modules.ALL&client_id={{client_id}}&response_type=code&access_type=offline&redirect_uri=" + location.protocol + '//' + location.host + "/generateToken"; } &lt;/script&gt; &lt;/html&gt; {{%/panel_with_adjustment%}} {{%note%}}{{%bold%}}Note:{{%/bold%}} Ensure you enter the {{%badge%}}Client ID{{%/badge%}} in line {{%bold%}}252{{%/bold%}}{{%/note%}} {{%panel_with_adjustment class="language-xml line-numbers" header="login.html" footer="button" scroll="set-scroll" %}}&lt;html&gt; &lt;/html&gt; &lt;meta charset="utf-8" /&gt; &lt;meta http-equiv="X-UA-Compatible" content="IE=edge"&gt; &lt;title&gt;CRM Lead Manager&lt;/title&gt; &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt; &lt;link rel="stylesheet" type="text/css" media="screen" href="main.css" /&gt; &lt;script src="main.js"&gt; &lt;/script&gt; &lt;link rel="stylesheet" type="text/css" media="screen" href="main.css" /&gt; &lt;link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"&gt; &lt;script src="https://js.zohostatic.com/catalystclient/1.0.0/catalystWebSDK.js"&gt; &lt;/script&gt; &lt;script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"&gt; &lt;/script&gt; &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"&gt; &lt;/script&gt; &lt;script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"&gt; &lt;/script&gt; &lt;script src="https://static.zohocdn.com/catalyst/sdk/js/4.4.0/catalystWebSDK.js"&gt; &lt;/script&gt; &lt;script src="/__catalyst/sdk/init.js"&gt; &lt;/script&gt; &lt;script&gt; catalyst.auth.signIn("login"); &lt;/script&gt; &lt;link href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"&gt; &lt;style&gt; #login { height: 100%; width: 100%; position: absolute; top: 0; bottom: 0; left: 0; right: 0; margin: auto; } &lt;/style&gt; &lt;body&gt; &lt;br&gt; &lt;center&gt; &lt;h1&gt;CRM Lead Manager&lt;/h1&gt; &lt;/center&gt; &lt;div id="login"&gt; &lt;/div&gt; &lt;/body&gt; &lt;/html&gt; {{%/panel_with_adjustment%}} {{%panel_with_adjustment class="language-css line-numbers" header="main.css" footer="button" scroll="set-scroll" %}}#dataTable { font-family: Arial, Helvetica, sans-serif; border-collapse: collapse; width: 100%; } #dataTable td, #dataTable th { border: 1px solid #ddd; padding: 8px; } #dataTable tr:nth-child(even){background-color: #f2f2f2;} #dataTable tr:hover {background-color: #ddd;} #dataTable th { padding-top: 12px; padding-bottom: 12px; text-align: left; background-color: #007bff; color: white; } .vertical-alignment-helper { display: table; height: 100%; width: 100%; pointer-events: none; } .vertical-align-center { display: table-cell; vertical-align: middle; pointer-events: none; } .modal-content { width: inherit; max-width: inherit; height: inherit; margin: 0 auto; pointer-events: all; } {{%/panel_with_adjustment%}} {{%panel_with_adjustment class="language-javascript line-numbers" header="main.js" footer="button" scroll="set-scroll" %}}function createLead() { debugger; $("#loader").show(); var firstName = $("#firstName").val(); var lastName = $("#lastName").val(); if (lastName == "") { alert("Kindly Enter the Last Name"); $("#loader").hide(); return; } var companyName = $("#companyName").val(); var email = $("#email").val(); var state = $("#state").val(); var phone = $("#phone").val(); var leadSource = $("#leadSource").val(); $.ajax({ url: "/crmData", type: "post", contentType: "application/json", data: JSON.stringify({ "First_Name": firstName, "Last_Name": lastName, "Company": companyName, "Email": email, "State": state, "Phone": phone, "Lead_Source": leadSource, }), success: function (data) { debugger; $('#leads').trigger("reset"); $("#myModalLabel").html("Success"); $("#message").html("Lead Created Successfully"); $("#loader").hide(); $('#myModal').modal('show'); }, error: function (error) { $('#leads').trigger("reset"); $("#myModalLabel").html("Failure"); $("#message").html("Please try again after Sometime"); $("#loader").hide(); $('#myModal').modal('show'); } }); } function logout() { var redirectURL = "/login.html"; //Add your app domain var auth = catalyst.auth; auth.signOut(redirectURL); } function getUserDetails() { $("#main").hide(); $("#connect").hide(); catalyst.auth.isUserAuthenticated().then(result =&gt; { console.log(result) $("#loader").show(); $.ajax({ url: "/getUserDetails", type: "get", success: function (data) { $("#loader").hide(); if (data.userId) { $("#main").show(); $("#connect").hide(); } else { $("#connect").show(); $("#main").hide(); } }, error: function (error) { $("#myModalLabel").html("Failure"); $("#message").html("Please try again after Sometime"); $("#loader").hide(); $('#myModal').modal('show'); } }); }).catch(err =&gt; { document.body.innerHTML = 'You are not logged in. Please log in to continue. Redirecting you to the login page..'; setTimeout(function () { window.location.href = "login.html"; }, 3000); }); } function getLeads() { debugger; var tableContainer = document.getElementById("showData"); tableContainer.innerHTML = ""; $("#loaders").show(); $.ajax({ url: "/crmData", type: "get", success: function (data) { debugger; var reqData = getRequiredData(data.data); $("#loaders").hide(); renderTable(reqData); }, error: function (error) { $("#myModalLabel").html("Failure"); $("#message").html("Please try again after Sometime"); $("#loader").hide(); $('#myModal').modal('show'); } }); } function showDeletePopup(leadID) { $('#ModalDanger').modal('show'); var deleteBtn = document.getElementById("delete-btn"); deleteBtn.value = leadID; } function deleteLead() { var leadID = document.getElementById('delete-btn').value; $.ajax({ url: "/crmData/" + leadID, type: "delete", success: function (data) { debugger; $('#ModalDanger').modal('toggle'); $("#myModalLabel").html("Success"); $("#message").html("Lead Deleted Successfully"); $('#myModal').modal('show'); setTimeout(function () { location.reload(); }, 3000); }, error: function (error) { $("#myModalLabel").html("Failure"); $("#message").html("Please try again after Sometime"); $("#loader").hide(); $('#myModal').modal('show'); } }); } function showEditPopup(leadID) { $.ajax({ url: "/crmData/" + leadID, type: "get", success: function (data) { debugger; var respData = data.data; $('#editfirstName').val(respData[0].First_Name); $('#editlastName').val(respData[0].Last_Name); $('#editcompanyName').val(respData[0].Company); $('#editemail').val(respData[0].Email); $('#editstate').val(respData[0].State); $('#editphone').val(respData[0].Phone); $('#editleadSource').val(respData[0].Lead_Source); $('#editBtn').val(respData[0].id); $('#editfirstName').html(respData[0].First_Name); $('#editlastName').html(respData[0].Last_Name); $('#editcompanyName').html(respData[0].Company); $('#editemail').html(respData[0].Email); $('#editstate').html(respData[0].State); $('#editphone').html(respData[0].Phone); $('#editleadSource').html(respData[0].Lead_Source); $('#editForm').modal('show'); }, error: function (error) { $("#myModalLabel").html("Failure"); $("#message").html("Please try again after Sometime"); $("#loader").hide(); $('#myModal').modal('show'); } }); } function editLead() { var firstName = $("#editfirstName").val(); var lastName = $("#editlastName").val(); if (lastName == "") { alert("Kindly Enter the Last Name"); return; } var companyName = $("#editcompanyName").val(); var email = $("#editemail").val(); var state = $("#editstate").val(); var phone = $("#editphone").val(); var leadSource = $("#editleadSource").val(); var leadID = $("#editBtn").val(); $.ajax({ url: "/crmData/" + leadID, type: "put", contentType: "application/json", data: JSON.stringify({ "First_Name": firstName, "Last_Name": lastName, "Company": companyName, "Email": email, "State": state, "Phone": phone, "Lead_Source": leadSource }), success: function (data) { debugger; $('#editForm').modal('toggle'); $("#myModalLabel").html("Success"); $("#message").html("Lead Edited Successfully"); $('#myModal').modal('show'); setTimeout(function () { location.reload(); }, 3000); }, error: function (error) { $('#leads').trigger("reset"); $("#myModalLabel").html("Failure"); $("#message").html("Please try again after Sometime"); $("#loader").hide(); $('#myModal').modal('show'); } }); } function getRequiredData(data) { var i; var resp = []; for (i = 0; i &lt; data.length; i++) { var gulp = { "First Name": data[i].First_Name, "Last Name": data[i].Last_Name, "Phone": data[i].Phone, "Email": data[i].Email, "Company": data[i].Company, "Edit": '&lt;center&gt;&lt;a href=&quot;javascript:showEditPopup(\'' + data[i].id + '\')&quot;&gt;&#9998;︎&lt;/a&gt;&lt;/center&gt;', "Delete": '&lt;center&gt;&lt;a href=&quot;javascript:showDeletePopup(\'' + data[i].id + '\')&quot;&gt;&#128465;︎&lt;/a&gt;&lt;/center&gt;' } resp.push(gulp); } console.log(resp); return resp; } function renderTable(respData) { var col = []; for (var i = 0; i &lt; respData.length; i++) { for (var key in respData[i]) { if (col.indexOf(key) === -1) { col.push(key); } } } var table = document.createElement("table"); table.id = "dataTable"; var tr = table.insertRow(-1); for (var i = 0; i &lt; col.length; i++) { var th = document.createElement("th"); th.innerHTML = col[i]; tr.appendChild(th); } for (var i = 0; i &lt; respData.length; i++) { tr = table.insertRow(-1); for (var j = 0; j &lt; col.length; j++) { var tabCell = tr.insertCell(-1); tabCell.innerHTML = respData[i][col[j]]; } } var divContainer = document.getElementById("showData"); divContainer.innerHTML = ""; divContainer.appendChild(table); } {{%/panel_with_adjustment%}} {{%panel_with_adjustment class="language-xml line-numbers" header="pom.xml" footer="button" scroll="set-scroll" %}}&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"&gt; &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt; &lt;parent&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt; &lt;version&gt;3.2.12-SNAPSHOT&lt;/version&gt; &lt;relativePath/&gt; &lt;!-- lookup parent from repository --&gt; &lt;/parent&gt; &lt;groupId&gt;com.catalyst.appsail&lt;/groupId&gt; &lt;artifactId&gt;leadmanager&lt;/artifactId&gt; &lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt; &lt;name&gt;leadmanager&lt;/name&gt; &lt;description&gt;Leadmanager Tutorial&lt;/description&gt; &lt;url/&gt; &lt;licenses&gt; &lt;license/&gt; &lt;/licenses&gt; &lt;developers&gt; &lt;developer/&gt; &lt;/developers&gt; &lt;scm&gt; &lt;connection/&gt; &lt;developerConnection/&gt; &lt;tag/&gt; &lt;url/&gt; &lt;/scm&gt; &lt;properties&gt; &lt;java.version&gt;17&lt;/java.version&gt; &lt;/properties&gt; &lt;dependencies&gt; &lt;dependency&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt; &lt;scope&gt;test&lt;/scope&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;com.zoho.catalyst&lt;/groupId&gt; &lt;artifactId&gt;java-sdk&lt;/artifactId&gt; &lt;version&gt;2.0.0-beta04&lt;/version&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;com.squareup.okhttp3&lt;/groupId&gt; &lt;artifactId&gt;okhttp&lt;/artifactId&gt; &lt;version&gt;3.9.0&lt;/version&gt; &lt;scope&gt;compile&lt;/scope&gt; &lt;/dependency&gt; &lt;/dependencies&gt; &lt;build&gt; &lt;plugins&gt; &lt;plugin&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt; &lt;/plugin&gt; &lt;/plugins&gt; &lt;/build&gt; &lt;repositories&gt; &lt;repository&gt; &lt;id&gt;spring-snapshots&lt;/id&gt; &lt;name&gt;Spring Snapshots&lt;/name&gt; &lt;url&gt;https://repo.spring.io/snapshot&lt;/url&gt; &lt;releases&gt; &lt;enabled&gt;false&lt;/enabled&gt; &lt;/releases&gt; &lt;/repository&gt; &lt;repository&gt; &lt;id&gt;java-sdk&lt;/id&gt; &lt;url&gt;https://maven.zohodl.com&lt;/url&gt; &lt;/repository&gt; &lt;/repositories&gt; &lt;pluginRepositories&gt; &lt;pluginRepository&gt; &lt;id&gt;spring-snapshots&lt;/id&gt; &lt;name&gt;Spring Snapshots&lt;/name&gt; &lt;url&gt;https://repo.spring.io/snapshot&lt;/url&gt; &lt;releases&gt; &lt;enabled&gt;false&lt;/enabled&gt; &lt;/releases&gt; &lt;/pluginRepository&gt; &lt;/pluginRepositories&gt; &lt;/project&gt; {{%/panel_with_adjustment%}} Addionally, you will also need to update the {{%badge%}}**app-config.json**{{%/badge%}} file. {{%panel_with_adjustment class="language-json line-numbers" header="app-config.json" footer="button" scroll="set-scroll" %}}{ "command": "java -jar leadmanager-0.0.1-SNAPSHOT.jar", "build_path": "./target", "stack": "java17", "env_variables": {}, "memory": 256, "scripts": { "preserve": "./mvnw clean package", "predeploy": "./mvnw clean package" }, "raw": {}, "platform": "javase", "catalyst_auth": true, "login_redirect": "/index.html" } {{%/panel_with_adjustment%}} <!-- {{%note%}}{{%bold%}}Note:{{%/bold%}} Ensure you provide the right value for the {{%badge%}}{{%bold%}}buildpath{{%/bold%}}{{%/badge%}} key.{{%/note%}} --> Now let's go over the logic and functionality of the application code. * The {{%badge%}}login.html{{%/badge%}} file in the client component enables Catalyst Embedded Authentication login, allowing you to log in using the Zoho social login. * The {{%badge%}}index.html{{%/badge%}} file contains the code for the front-end of the client. It defines a function {{%badge%}}navigate(){{%/badge%}} that enables the connection to the CRM account by passing the required authorization information such as the {{%badge%}}Client ID{{%/badge%}} and the scope. * The backend logic of the application defines the following APIs that perform various actions: - {{%badge%}}**/generateToken**{{%/badge%}}: Obtains the *Refresh Token* by calling the {{%badge%}}getRefreshToken(){{%/badge%}} function, and inserts it along with the {{%badge%}}userID{{%/badge%}} of the current user in the {{%badge%}}Token{{%/badge%}} table in the *Data Store*. It then redirects to the index page of the client. - {{%badge%}}**/getUserDetails**{{%/badge%}}: Fetches the user details by calling the {{%badge%}}getUserDetails(){{%/badge%}} function. If there is no record in the table, a JSON response with the {{%badge%}}userID{{%/badge%}} alone is sent. If the record exists in the table, it is sent along with the {{%badge%}}userID{{%/badge%}}. - {{%badge%}}**/crmData**{{%/badge%}}: This route defines the path of all leads in the Leads module. The Node function executes the HTTP {{%badge%}}GET{{%/badge%}} and {{%badge%}}POST{{%/badge%}} operations to fetch all leads or create a new lead using this route, respectively. - {{%badge%}}**/crmData/:id**{{%/badge%}}: This route defines the path of a particular lead in the Leads module. The {{%badge%}}id{{%/badge%}} represents the unique ID of the lead in CRM. The function executes the HTTP {{%badge%}}PUT{{%/badge%}} and {{%badge%}}DELETE{{%/badge%}} operations to edit or delete a lead, respectively, using this route. * The backend logic is implemented using the following functions that are called by the APIs: - {{%badge%}}**getRefreshToken()**{{%/badge%}}: Fetches the *Refresh Token* by passing the {{%badge%}}Client ID{{%/badge%}}, {{%badge%}}Client Secret{{%/badge%}}, *Redirect URI* and other required values as query string parameters. - {{%badge%}}**getAccessToken()**{{%/badge%}}: Fetches the *Access Token* by passing the *Refresh Token* queried from the Token table using {{%link href="/en/cloud-scale/help/zcql/introduction/" %}}ZCQL{{%/link%}}, and other required parameters. The Access Token is fetched each time an operation needs to be performed on the CRM module, such as adding a lead or editing a lead. - {{%badge%}}**getResponse()**{{%/badge%}}: Passes the *Access Token* fetched to obtain the authorization needed to perform each action on the CRM module. This function is called with each {{%badge%}}/crmData{{%/badge%}} and {{%badge%}}/crmData/:id{{%/badge%}} API to authorize the request. - {{%badge%}}**getUserDetails()**{{%/badge%}}: Fetches the record from the *Token* table that contains the *Refresh Token*, by passing the {{%badge%}}userID{{%/badge%}}. * {{%badge%}}**main.js**{{%/badge%}}: It is the JavaScript function in the client component that parses the JSON responses obtained from the function and renders them in the {{%badge%}}index.html{{%/badge%}} page. This function defines the actions for all the UI elements in the client application. For example, {{%badge%}}getLeads(){{%/badge%}} obtains all leads from the function response and renders them in the client, and {{%badge%}}showEditPopup(){{%/badge%}} defines the actions for editing a lead. -------------------------------------------------------------------------------- title: "Test the Application" description: "Build a Lead Manager application and host it on AppSail. The app connects to your Zoho CRM account using Catalyst connectors, and enables you to view, create, update, or delete leads from the Leads module in your CRM." last_updated: "2026-03-18T07:41:08.696Z" source: "https://docs.catalyst.zoho.com/en/tutorials/leadmanager-appsail/springboot/test-app/" service: "All Services" related: - CLI Help Documentation (/en/cli/v1/cli-command-reference/) - Serve Resources (/en/cli/v1/serve-resources/introduction/) -------------------------------------------------------------------------------- # Test the Application Before you deploy the application to the remote console, you can {{%link href="/en/cli/v1/serve-resources/introduction" %}}test the application on a local server{{%/link%}} and check if everything works fine using the Catalyst CLI. To serve the Catalyst project locally, execute the following command from your project directory: {{%cli%}}catalyst serve{{%/cli%}} The Lead Manager application will now be served at default {{%badge%}}port 3000{{%/badge%}}. The local endpoint URLs of the components are displayed. {{%info%}}{{%bold%}}Info:{{%/bold%}} Every time you access the home page or any of the sub-pages of your client or the function, the CLI will display a live log of the URL accessed, along with the HTTP request method.{{%/info%}} {{%note%}}{{%bold%}}Note:{{%/bold%}} Ensure you have provided the required {{%bold%}}Authorized Redirect URIs{{%/bold%}} when you {{%link href="/en/tutorials/leadmanager-appsail/express/register-client/" %}}registered the client in Step {{%bold%}}4{{%/bold%}}{{%/link%}}.{{%/note%}} <br /> You can now open the application in a browser using the local URL of the client displayed in the CLI. You will initially be redirected to the login page. If you configure a sign-up action on your own, you can sign up first, then log in to the application. Alternatively, you can also log in using the *Zoho Social Login*. <br /> You will be redirected to the permissions page. Accept the permissions requested by the app to access your Zoho account details. You will then be redirected back to the application. Click the **Zoho CRM** icon in this page to connect to Zoho CRM. <br /> You must now **choose the CRM account** that you wish to connect with the Lead Manager app, then click **Submit**. <br /> All your existing developer, sandbox, and production accounts will be listed. Click **Accept** to allow the *Lead Manager* app to access your Zoho CRM modules. <br /> You will be redirected back to the application. You can now create and manage leads in your configured Zoho CRM account directly from this application. To add a lead, enter the details of the lead in the *Add a Lead* section and click **Add Lead**. <br /> A confirmation pop-up will display the status every time you add, edit, or delete a lead. <br /> You can click the **Manage Leads** tab to view all your leads from the *Leads* module. You can **edit** or **delete** any of them by clicking their respective icons in the table. <br /> You can update a lead’s information, then click **Edit**. <br /> If you click the **delete** icon, you must confirm the action in the confirmation pop-up. <br /> You can also check the *Refresh Token* and {{%badge%}}userID{{%/badge%}} values populated in the **Data Store** from your Catalyst console. Navigate to the **Data View** section of the *Token* table to view the record that was added. <br /> If you delete this entry, you will have to authenticate your credentials in the client application and establish a connection to your CRM account again. You can log out of the application by clicking **Logout**. You can quit the {{%badge%}}serve{{%/badge%}} session in your terminal by executing the command to kill a running process, based on your OS. If this setup is working correctly, we can deploy the application to production. -------------------------------------------------------------------------------- title: "Deploy the Application" description: "Build a Lead Manager application and host it on AppSail. The app connects to your Zoho CRM account using Catalyst connectors, and enables you to view, create, update, or delete leads from the Leads module in your CRM." last_updated: "2026-03-18T07:41:08.696Z" source: "https://docs.catalyst.zoho.com/en/tutorials/leadmanager-appsail/springboot/deploy-app/" service: "All Services" related: - CLI Help Documentation (/en/cli/v1/cli-command-reference/) - Deploy Resources (/en/cli/v1/deploy-resources/introduction/) - AppSail Help Documentation (/en/serverless/help/appsail/introduction/) -------------------------------------------------------------------------------- # Deploy the Application You can now deploy the application to the remote console. {{%note%}}{{%bold%}}Note:{{%/bold%}} Since you had already logged into the {{%bold%}}Lead Manager{{%/bold%}} application from the local server, a {{%italics%}}Refresh Token{{%/italics%}} would have already been generated. This token will continue to authenticate your access.{{%/note%}} To {{%link href="/en/cli/v1/deploy-resources/introduction" %}}deploy your Catalyst project from the CLI{{%/link%}}, run the following command in your terminal from your project directory: {{%cli%}}catalyst deploy{{%/cli%}} The function is deployed first, followed by the client component. The app URLs of the components will be displayed. <br /> The application is now deployed to the Catalyst console. Now, if you once again navigate to the AppSail component located under the *Serverless* section, you will be able to acquire the application's invocation URL. <br /> In this section you will also have access to a live dashboard denoting the number of instances the Lead Manager app service has spawned at any given moment. Using this section you will also be able configure and manage the AppSail service. You can find out more about this {{%link href="/en/serverless/help/appsail/console/introduction/" %}}here{{%/link%}}. You can use the invocation URL in a browser to access the deployed application. Lead Manager application can now be accessed from its {{%link href="/en/cloud-scale/help/web-client-hosting/introduction" %}}web app URL{{%/link%}}. <br />