Kaizen #131 - Bulk Write for parent-child records using Scala SDK

Kaizen #131 - Bulk Write for parent-child records using Scala SDK

Hello and welcome back to this week's Kaizen!
Last week, we discussed how to configure and initialize the Zoho CRM Scala SDK. This week, we will be exploring the Bulk Write API and its capabilities. Specifically, we will focus on executing bulk write operations for parent-child records in a single operation, and how to do this using Scala SDK.

Quick Recap of Bulk Write API

Bulk Write API facilitates efficient insertion, updation, or upsertion of large datasets into your CRM account. It operates asynchronously, scheduling jobs to handle data operations. Upon completion, notifications are sent to the specified callback URL or the job status can be checked periodically.

When to use Bulk Write API?

  • When scheduling a job to import a massive volume of data.
  • When needing to process more than 100 records in a single API call.
  • When conducting background processes like migration or initial data sync between Zoho CRM and external services.

Steps to Use Bulk Write API:

  1. Prepare CSV File: Create a CSV file with field API names as the first row and data in subsequent rows.
  2. Upload Zip File: Compress the CSV file into a zip format and upload it via a POST request.
  3. Create Bulk Write Job: Use the uploaded file ID, callback URL, and field API names to create a bulk write job for insertion, update, or upsert operations.
  4. Check Job Status: Monitor job status through polling or callback methods. Status could be ADDED, INPROGRESS, or COMPLETED.
  5. Download Result: Retrieve the result of the bulk write job, typically a CSV file with job details, using the provided download URL.
In our previous Kaizen posts - Bulk Write API Part I and Part II, we have extensively covered the Bulk Write API, complete with examples and sample codes for the PHP SDK. We highly recommend referring to those posts before reading further to gain a better understanding of the Bulk Write API.
With the release of our V6 APIs, we have introduced a significant enhancement to our Bulk Write API functionality. Previously, performing bulk write operations required separate API calls for parent and each child module. But with this enhancement, you can now import them all in a single, operation or API call.

Field Mappings for parent-child records in a single API call

When configuring field mappings for bulk write operations involving parent-child records in a single API call, there are two key aspects to consider: creating the CSV file containing the data and constructing the input JSON for the bulk write job. 

Creating the data CSV file:

To set up the data for a bulk write operation involving parent-child records, you need to prepare separate CSV files - one for the parent module records, and one each for each child module records. In these CSV files, appropriate field mappings for both parent and child records need to be defined. 

The parent CSV file will contain the parent records, while the child CSV file will contain the child records. To make sure that each child record is linked to its respective parent record, we will add an extra column (MappingID in the image below) to both the parent and child CSV files. This column will have a unique identifier value for each parent record. For each record in the child CSV file, the value in the identifier column should match the value of the identifier of the parent record in the parent CSV file. This ensures an accurate relationship between the parent and child records during the bulk write operation.

Please be aware that the mapping of values is solely dependent on the mappings defined in the input JSON. In this case, the column names in the CSV file serve only as a reference for you. Please refer to the notes section towards the end of this document for more details.


Creating the CSV file remains consistent across all types of child records, and we have already discussed how each child record is linked to its respective parent record in the CSV file. To facilitate the same linkage in the input JSON, we have introduced a new key called parent_column_index. This key assists us in specifying which column in the child module's CSV file contains the identifier or index linking it to the parent record. In the upcoming sections, we will explore preparing the input JSON for various types of child records.

Additionally, since we have multiple CSV files in the zip file, we have introduced another new key named file_names in resources array. file_names helps in correctly mapping each CSV file to its corresponding module.

Ensure that when adding parent and child records in a single operation, the parent module details should be listed first, followed by the child module details in the resource array of the input body.

1. Multiselect Lookup Fields

In scenarios involving multiselect lookup fields, the Bulk Write API now allows for the import of both parent and child records in a single operation.
In the context of multiselect lookup fields, the parent module refers to the primary module where the multiselect lookup field is added. For instance, in our example, consider a multiselect lookup field in the Leads module linking to the Products module.

Parent Module : Leads 
Child module : The linking module that establishes the relationship between the parent module and the related records (LeadsXProducts)

Here are the sample files for the "LeadsXProducts" case:

Leads.csv (Parent)

LeadsXProducts.csv (Child)

Given below is a sample input JSON for this bulk write job. Please note that the index of the child linking column should be mapped under the key index, and the index of the parent column index should be mapped under parent_column_index

To map the child records to their corresponding parent records (linking module), you must use the field API name of the lookup field that links to the parent module. For example, in this case, the API name of the lookup field linking to the Leads module from the LeadsXProducts is Leads.

{
"operation": "insert",
"ignore_empty": true,
"callback": {
"method": "post"
},
"resource": [
{
"type": "data",
"module": { 
"api_name": "Leads" //parent module API name
},
"file_id": "4876876000006855001",
"file_names": [
"Leads.csv" //parent records CSV file
],
"field_mappings": [ // field mappings for the parent record fields
{
"api_name": "Company", //field API name
"index": 0 //index in the CSV file
},
{
"api_name": "First_Name",
"index": 1
},
{
"api_name": "Last_Name",
"index": 2
},
{
"api_name": "Email",
"index": 3
},
{
"api_name": "Phone",
"index": 4
}
]
},
{
"type": "data",
"module": { 
"api_name": "LeadsXProducts" //child module API name
},
"file_id": "4876876000006855001",
"file_names": [
"LeadsXProducts.csv" //child records CSV file
],
"field_mappings": [
{
"api_name": "Products",
"find_by": "id",
"index": 0
},
{
"api_name": "Leads", //field API name of the lookup field in the Linking Module
"parent_column_index": 5, // the index of the identifier column in the parent CSV file
"index": 1 //index of the identifier column in the child CSV file
}
]
}
]
}

The following is a sample code snippet for the Scala SDK, to achieve the same functionality. Find the complete code here.

var module = new MinifiedModule() // Create a new instance of MinifiedModule
module.setAPIName(Option("Leads")) // Set the API name for the module to "Leads"
resourceIns.setModule(Option(module))
resourceIns.setFileId(Option("4876876000006899001")) // Set the file ID for the resource instance 
resourceIns.setIgnoreEmpty(Option(true))
var filenames = new ArrayBuffer[String] // Create a new ArrayBuffer to store file names
filenames.addOne("Leads.csv")
resourceIns.setFileNames(filenames) // Set the file names for the resource instance
// Create a new ArrayBuffer to store field mappings
var fieldMappings: ArrayBuffer[FieldMapping] = new ArrayBuffer[FieldMapping]
// Create a new FieldMapping instance for each field
var fieldMapping: FieldMapping = null
fieldMapping = new FieldMapping
fieldMapping.setAPIName(Option("Company"))
fieldMapping.setIndex(Option(0))
fieldMappings.addOne(fieldMapping)
.
.
// Set the field mappings for the resource instance
resourceIns.setFieldMappings(fieldMappings)
resource.addOne(resourceIns)
requestWrapper.setResource(resource)
resourceIns = new Resource
resourceIns.setType(new Choice[String]("data"))
module = new MinifiedModule()
module.setAPIName(Option("LeadsXProducts"))
resourceIns.setModule(Option(module))
resourceIns.setFileId(Option("4876876000006899001"))
resourceIns.setIgnoreEmpty(Option(true))
filenames = new ArrayBuffer[String]
filenames.addOne("LeadsXProducts.csv")
resourceIns.setFileNames(filenames)
fieldMappings = new ArrayBuffer[FieldMapping]
fieldMapping = new FieldMapping
fieldMapping.setAPIName(Option("Products"))
fieldMapping.setFindBy(Option("id"))
fieldMapping.setIndex(Option(0))
fieldMappings.addOne(fieldMapping)
fieldMapping = new FieldMapping
fieldMapping.setAPIName(Option("Leads")) //Specify the API name of the lookup filed in the Linking Module
fieldMapping.setParentColumnIndex(Option(5)) //Specify the index of the identifier column in the parent CSV file
fieldMapping.setIndex(Option(1)) //Specify the index of the identifier column in the child CSV file
fieldMappings.addOne(fieldMapping)
resourceIns.setFieldMappings(fieldMappings)
resource.addOne(resourceIns)
requestWrapper.setResource(resource)

2. Multi-User Lookup fields

In case of multi-user lookup fields, the parent module remains the module where the multi-user field is added. The child module is the lookup module created to facilitate this relationship.
For instance, let's consider a scenario where a multi-user field labeled Referred By is added in the Leads module, linking to the Users module.

Parent module : Leads 
Child module : The linking module, LeadsXUsers.

To get more information about the child module, please utilize the Get Modules API. You can get the details of the fields within the child module using the Fields API
Here is a sample CSV for adding a multi-user field records along with the parent records:

LeadsXUsers.csv

Please ensure that you create a zip file containing the corresponding CSV files, upload it to the platform and then initiate the bulk write job using the file ID. The values for index and parent_column_index will vary based on your specific CSV files.

To create a bulk write job using Create Bulk Write job API, add the following code snippet to your resource array.
{
"type": "data",
"module": { 
"api_name": "Leads_X_Users" // child module
},
"file_id": "4876876000006887001",
"file_names": [
"LeadsXUsers.csv" //child records CSV file name
],
"field_mappings": [
{
"api_name": "Referred_User",
"find_by": "id",
"index": 0
},
{
"api_name": "userlookup221_11", //API name of the Leads lookup field in LeadsXUsers module
"parent_column_index": 5, // the index of the identifier column in the parent CSV file
"index": 1 // the index of the identifier column in the child CSV file
}
]
}

To do the same using Scala SDK, add the following code snippet to your code:

resourceIns = new Resource
resourceIns.setType(new Choice[String]("data"))
module = new MinifiedModule()
module.setAPIName(Option("Leads_X_Users"))
resourceIns.setModule(Option(module))
resourceIns.setFileId(Option("4876876000006904001"))
resourceIns.setIgnoreEmpty(Option(true))
filenames = new ArrayBuffer[String]
filenames.addOne("LeadsXUsers.csv")
resourceIns.setFileNames(filenames)
fieldMappings = new ArrayBuffer[FieldMapping]
fieldMapping = new FieldMapping
fieldMapping.setAPIName(Option("Referred_User"))
fieldMapping.setFindBy(Option("id"))
fieldMapping.setIndex(Option(0))
fieldMappings.addOne(fieldMapping)
fieldMapping = new FieldMapping
fieldMapping.setAPIName(Option("userlookup221_11"))
fieldMapping.setParentColumnIndex(Option(5))
fieldMapping.setIndex(Option(1))
fieldMappings.addOne(fieldMapping)
resourceIns.setFieldMappings(fieldMappings)
resource.addOne(resourceIns)
requestWrapper.setResource(resource)

3. Subform data

To import subform data along with parent records in a single operation, you must include both the parent and subform CSV files within a zip file and upload it. In this context, the parent module refers to the module where the subform is added, and the child module is the subform module.

For instance, consider a subform named Alternate Address in the Leads module, with fields such as City and State

Parent module : Leads
Child module : Alternate_Address (api name of the Subform module). 

In the subform CSV file (Alternate_Address.csv), in addition to the data columns, include a column to denote the linkage to the parent record.
Once the zip file containing both the parent and subform CSV files is prepared, proceed to upload it to initiate the import process. When you create the bulk write job, ensure to specify the appropriate values for index and parent_column_index based on your specific CSV files in the input.

Here is a sample CSV for the subform data, corresponding to the parent CSV provided earlier.

Alternate_Address.csv

To create a bulk write job using Create Bulk Write job API to import the subform data, add the following code snippet to your resource array.

{
"type": "data",
"module": { 
"api_name": "Alternate_Address" //Subform module API name
},  
"file_id": "4876876000006915001",
"file_names": [
"Alternate_Address.csv" //child (subform) records CSV
],
"field_mappings": [
{
"api_name": "State",
"index": 0
},
{
"api_name": "City",
"index": 1
},
{
"api_name": "Parent_Id", //Leads lookup field in the subform module
"parent_column_index": 5,
"index": 2
}
]
}

To do the same using Scala SDK, add the following code snippet to your code:

resourceIns = new Resource
resourceIns.setType(new Choice[String]("data"))
module = new MinifiedModule()
module.setAPIName(Option("Alternate_Address"))
resourceIns.setModule(Option(module))
resourceIns.setFileId(Option("4876876000006920001"))
resourceIns.setIgnoreEmpty(Option(true))
filenames = new ArrayBuffer[String]
filenames.addOne("Alternate_Address.csv")
resourceIns.setFileNames(filenames)
fieldMappings = new ArrayBuffer[FieldMapping]
fieldMapping = new FieldMapping
fieldMapping.setAPIName(Option("State"))
fieldMapping.setIndex(Option(0))
fieldMappings.addOne(fieldMapping)
fieldMapping = new FieldMapping
fieldMapping.setAPIName(Option("City"))
fieldMapping.setIndex(Option(1))
fieldMappings.addOne(fieldMapping)
fieldMapping = new FieldMapping
fieldMapping.setAPIName(Option("Parent_Id"))
fieldMapping.setParentColumnIndex(Option(5))
fieldMapping.setIndex(Option(2))
fieldMappings.addOne(fieldMapping)
resourceIns.setFieldMappings(fieldMappings)
resource.addOne(resourceIns)
requestWrapper.setResource(resource)

4. Line Items

To import line items along with the parent records, an approach similar to handling subform data is used. The parent module is the module housing the parent records, while the child module corresponds to the line item field.

For instance, in the Quotes module, to import product details within the record, the child module should be Quoted_Items. 

Here is a sample CSV for importing the parent records to the Quotes module:

Quotes.csv

Given below is a sample CSV to add the product details in Quoted Items:

Quoted_Items.csv

Now to create a bulk write job for these records, here is a sample input JSON:

{
"operation": "insert",
"ignore_empty": true,
"callback": {
"method": "post"
},
"resource": [
{
"type": "data",
"module": { 
"api_name": "Quotes"
},
"file_id": "4876876000006949001",
"file_names": [
"Quotes.csv"
],
"field_mappings": [
{
"api_name": "Subject",
"index": 0
},
{
"api_name": "Deal_Name",
"find_by" : "id",
"index": 1
},
{
"api_name": "Quote_Stage",
"index": 2
},
{
"api_name": "Account_Name",
"find_by" : "id",
"index": 3
}
]
},
{
"type": "data",
"module": { 
"api_name": "Quoted_Items"
},
"file_id": "4876876000006949001",
"file_names": [
"Quoted_Items.csv"
],
"field_mappings": [
{
"api_name": "Product_Name",
"find_by" : "id",
"index": 0
},
{
"api_name": "Quantity",
"index": 1
},
{
"api_name": "Parent_Id",
"parent_column_index": 4,
"index": 2
}
]
}
]
}

To do the same using Scala SDK, add this code snippet to your file:

val bulkWriteOperations = new BulkWriteOperations
val requestWrapper = new RequestWrapper
val callback = new CallBack
callback.setUrl(Option("https://www.example.com/callback"))
callback.setMethod(new Choice[String]("post"))
requestWrapper.setCallback(Option(callback))
requestWrapper.setCharacterEncoding(Option("UTF-8"))
requestWrapper.setOperation(new Choice[String]("insert"))
requestWrapper.setIgnoreEmpty(Option(true))
val resource = new ArrayBuffer[Resource]
var resourceIns = new Resource
resourceIns.setType(new Choice[String]("data"))
var module = new MinifiedModule()
module.setAPIName(Option("Quotes"))
resourceIns.setModule(Option(module))
resourceIns.setFileId(Option("4876876000006953001"))
resourceIns.setIgnoreEmpty(Option(true))
var filenames = new ArrayBuffer[String]
filenames.addOne("Quotes.csv")
resourceIns.setFileNames(filenames)
var fieldMappings: ArrayBuffer[FieldMapping] = new ArrayBuffer[FieldMapping]
var fieldMapping: FieldMapping = null
fieldMapping = new FieldMapping
fieldMapping.setAPIName(Option("Subject"))
fieldMapping.setIndex(Option(0))
fieldMappings.addOne(fieldMapping)
fieldMapping = new FieldMapping
fieldMapping.setAPIName(Option("Deal_Name"))
fieldMapping.setFindBy(Option("id"))
fieldMapping.setIndex(Option(1))
fieldMappings.addOne(fieldMapping)
fieldMapping = new FieldMapping
fieldMapping.setAPIName(Option("Quote_Stage"))
fieldMapping.setIndex(Option(2))
fieldMappings.addOne(fieldMapping)
fieldMapping = new FieldMapping
fieldMapping.setAPIName(Option("Account_Name"))
fieldMapping.setIndex(Option(3))
fieldMapping.setFindBy(Option("id"))
fieldMappings.addOne(fieldMapping)
resourceIns.setFieldMappings(fieldMappings)
resource.addOne(resourceIns)
requestWrapper.setResource(resource)
resourceIns = new Resource
resourceIns.setType(new Choice[String]("data"))
module = new MinifiedModule()
module.setAPIName(Option("Quoted_Items"))
resourceIns.setModule(Option(module))
resourceIns.setFileId(Option("4876876000006953001"))
resourceIns.setIgnoreEmpty(Option(true))
filenames = new ArrayBuffer[String]
filenames.addOne("Quoted_Items.csv")
resourceIns.setFileNames(filenames)
fieldMappings = new ArrayBuffer[FieldMapping]
fieldMapping = new FieldMapping
fieldMapping.setAPIName(Option("Product_Name"))
fieldMapping.setFindBy(Option("id"))
fieldMapping.setIndex(Option(0))
fieldMappings.addOne(fieldMapping)
fieldMapping = new FieldMapping
fieldMapping.setAPIName(Option("Quantity"))
fieldMapping.setIndex(Option(1))
fieldMappings.addOne(fieldMapping)
fieldMapping = new FieldMapping
fieldMapping.setAPIName(Option("Parent_Id"))
fieldMapping.setParentColumnIndex(Option(4))
fieldMapping.setIndex(Option(2))
fieldMappings.addOne(fieldMapping)
resourceIns.setFieldMappings(fieldMappings)
resource.addOne(resourceIns)
requestWrapper.setResource(resource)

Notes : 

  • When importing a single CSV file (parent or child module records separately), field_mappings is an optional key in the resource array. If you skip this key, the field mappings must be defined using the column names in the CSV file. In such cases, the column names should correspond to the field API names. Additionally, all columns should be mapped with the correct API names, and there should not be any extra unmapped columns.
  • When importing parent and child records in a single API call, field_mappings is a mandatory key.
  • The identifier column in the parent and child CSV can have different column names, as the mapping is done based on the input JSON.

Points to remember

  • An uploaded file can be used for a single bulk write job only. If you want to retry the operation with the same data, upload the file again to generate a new file ID.
  • When adding parent and child records in a single operation, ensure that the parent module comes first, followed by the child module details in the resource array of the input body.
  • The parent and all child CSV files should be zipped into a single file and uploaded. You cannot use more than one zip file in a single bulk write job. 
  • Define appropriate mappings for both parent and child records using the parent_column_index and index key to establish the relationship.
  • Utilize the resources > file_names key to map the correct CSV with the appropriate module
  • For each parent in the parent records file:
    • By default, the limit for Subforms and Line Items is set to 200. While you can configure this limit for subforms in the UI, customization options are not available for Line Items.
    • MultiSelect Lookup fields have a maximum limit of 100. If you have more than 100 associations for a MultiSelect Lookup field, you may schedule additional bulk write jobs for the child records alone, importing 100 records at a time.
    • The maximum limit for Multi-User Lookup fields is restricted to 10
We hope that you found this post useful, and you have gained some insights into using the Bulk Write API effectively. If you have any queries, let us know in the comments below, or feel free to send an email to support@zohocrm.com. We would love to hear from you!

Recommended Reads :


    • Recent Topics

    • iOS App Version 3.0 - Customer list gone?

      Not sure when this changed, but I seem to have been updated to 3.0 for the phone app (on iOS). I'm pretty sure that I used to have a Customers button that allowed me, for example, to see what appointments a customer has. Has this disappeared or am I just
    • Zoho Signature, "For Demo Purpose Only Powered by Zoho Sign"

      How to disable this text on the documents for signature. "For Demo Purpose Only Powered by Zoho Sign"
    • Add Resource variable to notification email customisation for Event Type

      The notification email customisation feature for Event Type does not include a variable for the Resource field. Without this field, Zoho Bookings cannot be used by any business for resource-based services or event types e.g. room bookings, equipment bookings.
    • Can't find add role button, is iet st because I have the free subscription

      Trying to add my accountant in Zoho Books if I press the add accountant button, I get stuck as it says no such role exists, and won't let me continue, I can't find the add roles button, so I am stuck. Is it because I have the free subscription? Also can't
    • Calendar view all appointments in workspace

      In the Calendar page, add the ability to view all appointments in the Workspace. The Manage Calendars filter requires me to select at least one user or resource, and it only lets me select up to five of them. There's no filter option to view the entire
    • Tip #13: Identify where your bookings come from with Source Tracking

      Source tracking is the practice of identifying where your bookings originated. This is important, because online bookings come from a wide variety of sources like social media platforms, your website, email and ad campaigns, partner websites, organic
    • Unable to Add Notes

      I've had a user report that they are unable to add notes to account records. I attempted and found the same issue. There is no option to save the note.
    • Workflow Rule Alert Not Working

      I have a workflow rule set (that I've been using for years) that suddenly stopped working. Module - Leads Execute on - Create Alerts - Email Active - Yes When I create my lead I no longer receive my email notification. 
    • Can zoho sign collect data feeding Zoho Sign?

      I m sending contracts to client who are not in my zoho CRM database yet. Can the data they enter in Zoho sign contract I send them, (that includes...) official company name address first name second name etc, ...Create or update a contact / account
    • IMAP ACCOUNT ACCESS PROBLEM

      Hi! I moved from Gmail some time ago to ZOHO. It works fine and it worked till yesterday. I found out that on my MAC OSX mail client I can not receive emails from ZOHO using IMAP. Gmail is set to IMAP and works OK. My company email account uses POP and works good as well. Is there anybody else who has such problem or this might be something with my email client...? I didi check for the settings but everything is as it was from the beginning. Honestly, I didn't change anything recently. It just stopped.
    • Modified approved time log

      I can’t seem to find a way to make change to approve time log entry. The case is the following. We pay the employees every 2 weeks, so employe A enter is time for the 2 weeks and then submit his timesheet. Now is superior approve the time he worked via
    • I want to Show the product list based on the drop Down

      in quotation app , amc form form i have Department drop down field and in subform i have loop up field item description taken from the anothe app PRO I want to show the product list look up based on the deparment selected example if they selected deparment
    • Inventory Barcode Creation - Add Picture of Item

      Hi I am trying to set up bar code labels and include a picture of the item on the label - any idea on how to add that field to the barcode generator?
    • Shared Snippets Everyone

      Hi, Now that the Shared Snippets have been released and I think will be the most used feature implemented in 2023 :) Creating and Using Snippets in Ticket Responses - Online Help | Zoho Desk Maintain consistency in ticket responses with shared snippets
    • Topics assigned to Contacts in Campaigns

      I have yet to find an efficient way to assign topics to contacts in campaigns with the new system in place.  We have daily contacts added to our system through various forms and we have to manually go in and add topics to contacts before each email campaign
    • Zoho CRM email formatting issues

      I have been having a hard time with formatting email templates. It feels like Zoho email is "fighting my edits." It refuses to change size, font, etc. Sometimes, the template looks great, then when the email gets sent, it looks completely different- some
    • Weekly Tips : Seamlessly collaborate with Share Drafts in Zoho Mail

      Ever found yourself stuck wondering how to get input on an important email draft without actually sending it? Maybe you want a teammate’s feedback or approval from your manager—without exposing sensitive info. Or perhaps you are working across different
    • How to Share a workdrive folder outside organization ?

      Hi, Earlier we were using Google Suite and were able to share the google drive folders with external organization ( Auditors , marketing collaterals ) as most of them had a personal gmail account they were able to access it without any issue. How can
    • Zoho CRM Account Duplication via Credit Application Form

      Hi, We send a credit application link to our customers via email, which is managed through Zoho Campaigns. When a customer submits the form, it automatically creates a new account in Zoho CRM. We would like to know how to stop this from creating duplicate
    • Flexible Milestone Invoicing

      If your Zoho Projects portal is integrated with Zoho Invoice/Books, you can now create an invoice for your milestones. You can enable it under Integration Preference and invoice milestones regardless of the project's billing type. For instance, consider
    • The get records i am getting produts that show in the show in the sub form item list field

      The get records i am getting produts that show in the show in the sub form item list field if(input.Department != null) { // Get filtered records once creator_ptid = zoho.creator.getRecords("harshadgroup","item-master","All_Products","Department == \""
    • Add Zoho Form Submission as Attachment to Zoho CRM Deal using Zoho Deal ID

      Hi Zoho team, I have a Zoho Form in which one of the fields will be hidden but will be defaulted with the Zoho Deal ID. Once the form is submitted, I want to reattach the submitted form (and another uploaded file field) into Zoho CRM Deals record. The crazy part is that Deal Name and Stage are the only two fields available for mapping. I have the actual Deal ID. Why can't I just use that. Can you please fix it so that I can properly attach the submission using Zoho Deal ID instead of name/stage (which
    • Payment link showing as malicious

      We've had a few customers who have been unable to pay invoices as the payment link (the domain is zohosecurepay.eu) is showing as a malicious website in their browser. Could anyone help with this please?
    • Side bar menu

      It would be great if you could stop the auto collapse of expanded menus when selecting a different module. It would save a lot of mouse clicks for a lot of users that frequently switch between sales & purchases as we do, it's easier to collapse them manually when not required !
    • Add Microsoft Entra ID to Zoho One

      Hi! Have anyone tried the Zoho connection to Microsoft Entra ID (https://help.zoho.com/portal/en/kb/one/admin-guide/directory-stores/articles/add-microsoft-azure-to-zoho-one?action=kbArticleFollow&actionId=4014605732522 ) This is a big operation and you
    • Multiple Respondents for One Survey Submission?

      Does anyone know of a way to allow multiple respondents to complete only one  survey and then also see (while completing the survey) the responses for their fellow colleagues who already answered that question? The situation is that our new customers have within their own organization, multiple employees that will need to assist in the one survey response. Since we don't always know which new respondent is the "who" that will have the answer, we need multiple respondents to be able to view the response
    • Can you remove the title from the forms?

      I am placing the iframes for my forms on my website.  Is it possible to remove or hide the title of the form so that it doesn't show up on the website? Is it possible to place text in the form like "clicking submit will take you to paypal." thanks
    • Lost the ability to sort by ticket owner

      Hi all, in the last week or so, we have lost the ability to sort tickets by Ticket Owner. Unlike the other columns which we can hover over and click on to sort, Ticket Owner is no longer clickable. Is it just us, or are other customers seeing this too?
    • Mask Name Field in Report

      Is it possible to have the Name field as "Last Name, First Name" in a scheduled report.
    • Custom Project View by Project Group

      Hi Zoho Team, I used to have a custom project view which showed all my active projects (not cancelled or completed) and the list was separated into projects groups. Some time ago, possibly a couple of months ago, I began to see all projects even cancelled
    • Unable to attach the file via the API.

      We are trying to attach files to a Candidate in Zoho Recruit using the API. We reviewed the following API documentation: 🔗 Upload Attachment While this API does allow file attachment via a URL, that’s not what we want — we do not want to attach public-facing
    • Zoho Books (UK) needs to be able to submit a CT600 CTSA return

      As well as a VAT Return, most (if not all) small businesses have to submit a CT600 Corporation Tax Self-Assessment. There are many providers who do this (like Xero) bujt not Zoho. Can you add this to the request list please? Many thanks Steve
    • Stock Update After Approver 1 Approval in Multi-Level Approval Flow

      Hi Team, We have configured a multi-level approval process for POs/Bills. Our requirement is to update the item stock quantity based on the billed quantity immediately after Approver 1 approves the bill. Please find the script attached below. However,
    • Zoho Form Auto Fill

      I am setting up a Zoho form for my independent sales reps to request quotes. Their names are in the first field under a dropdown menu. The next field is their email address. I want the email address field to automatically be filled in when they select
    • Image Resolution Restriction Option in Zoho Forms File Upload

      Hi Zoho Forms Team, Greetings, We would like to request a feature enhancement for Zoho Forms regarding the file upload field. Currently, Zoho Forms allows us to restrict the file size of uploaded images, but not the image resolution (in megapixels). This
    • Can't select Leave type while applying a leave

      Hello, while trying to apply a leave, I can't find any leave type among the options in the Leave type select: Here are my leave settings. Daily: Hourly: Tried to clear cache and to navigate from another browser, but the problem persists. Any hint? Thank
    • Mes débuts sur Zoho Forms | 13 champs à l'export ! seulement

      Bonjour, je débute sur Zoho Forms, je viens de créer un formulaire avec tests dans la foulée et je n'ai que 13 champs qui remontent sur mon export CSV alors que j'ai plus de questions et champs qui devraient remonter. J'ai actuellement une formule payante
    • Introducing real-time document commenting and collaboration in Zoho Sign

      Hi, there! We are delighted to introduce Document commenting, a feature that helps you communicate with your recipients more efficiently for a streamlined document signing process. Some key benefits include: Collaborate with your recipients easily without
    • Adding Photos Into Form (as a form creator)

      As the form creator, is it possible to add images to my form? (I don’t mean adding an image upload field, but rather inserting a JPG file into the form so that users can view the image.)
    • [Training] AI-Powered Application Development Bootcamp 2.0 - Zoho Creator

      Hello everyone, Ready to take your app-building skills to the next level with the power of AI? We’re excited to invite you to AI-Powered Application Development Bootcamp 2.0—a 90-minute, live training session designed to help developers, business users,
    • Next Page