InvokeURL butchering JSON for OpenAI API calls

InvokeURL butchering JSON for OpenAI API calls

My organization works with mostly educational institutions. We have a custom module called "Schools", which is the user-entered school name they put when using our service (which they enter along with their state and zip code). We want to map this to a list of known schools from a public database that has both a standardized school name, address, phone number, and other data about the school (along with a unique identifier) stored in our org's Zoho Analytics database.

To accomplish this, we are trying to leverage OpenAI's API to find a "best match" of the unique ID. When a school is created in our system, I am getting the "State", "Zip", and entered school name. This runs a query in Zoho Analytics to return batches of 250 schools in that state at a time (to avoid API size problems), and runs this through OpenAI to find which in each batch is the closest match to what was entered, and saves that to a new array. This repeats for all schools in the state, then afterwards runs the set of "winners" through OpenAI one more time to get the best overall winner.

The problem is our API call to OpenAI - it continually returns 

{"error":{"message":"We could not parse the JSON body of your request. (HINT: This likely means you aren't using your HTTP library correctly. The OpenAI API expects a JSON payload, but what was sent was not valid JSON. If you have trouble figuring out how to fix this, please contact us through our help center at help.openai.com.)","type":"invalid_request_error","param":null,"code":null}}

I verified several times that my JSON body is indeed correct. I also have alternated between using "parameters" and "body", and various ways to stringify the payload - none of which have any improvement. Recommendations from ChatGPT believe that regardless of me specifying "content-type: application/json", it is still mangling the payload.

The worst part is - this actually worked just fine until last night (October 17, 2025), sometime around 5pm. I had been running the version of the script below to back-fill our existing school database, which had been calling this API every 45 seconds for a couple days without any errors. OpenAI insists they have not changed anything on their end, and zoho insists the same on theirs. Any help would be appreciated.

string standalone.SetSchoolAddressAPI()
{
PAGE_SIZE = 250;
random = randomNumber(1,50);
school = zoho.crm.searchRecords("Schools","(NCES_School_ID:equals:99)",1,random);
st_school_id = school.get(0).get("id");
info st_school_id;
school = zoho.crm.getRecordById("Schools",st_school_id);
school_name = ifnull(school.get("Name"),"");
acc_id = null;
if(school.containsKey("Account") && school.get("Account") != null && school.get("Account").containsKey("id"))
{
acc_id = school.get("Account").get("id");
}
account = Map();
if(acc_id != null)
{
account = zoho.crm.getRecordById("Accounts",acc_id);
}
account = ifnull(account,Map());
school_zip = ifnull(school.get("Zip"),account.get("Billing_Code"));
school_state = ifnull(school.get("State"),account.get("Billing_State"));
target_name = ifnull(school_name,"");
state_input = ifnull(school_state,"");
zip_input = ifnull(school_zip,"");
/***** --- Enforce state presence & normalize --- *****/
if(state_input == null || state_input == "")
{
update_map = Map();
update_map.put("NCES_School_ID",null);
update_map.put("Country","");
update_map.put("State",school_state);
zoho.crm.updateRecord("Schools",st_school_id,update_map);
return "No state on record; aborting NCES match.";
}
state_input = state_input.trim();
/***** === Zoho Analytics fixed config (unchanged) === *****/
workspace_name = "Zoho CRM Analytics";
view_name = "NCES Schools";
owner_email = "xxx";
ws_enc = zoho.encryption.urlEncode(workspace_name);
view_enc = zoho.encryption.urlEncode(view_name);
endpoint = "https://analyticsapi.zoho.com/api/" + owner_email + "/" + ws_enc + "/" + view_enc;
/***** === Step 1: Count rows by state === *****/
state_esc = state_input.replaceAll("'","''");
count_sql = "select count(*) as total_count from \"" + view_name + "\" where \"State\"='" + state_esc + "'";
count_params = Map();
count_params.put("ZOHO_ACTION","EXPORT");
count_params.put("ZOHO_OUTPUT_FORMAT","JSON");
count_params.put("ZOHO_SQLQUERY",count_sql);
count_params.put("ZOHO_API_VERSION","1.0");
count_resp = invokeurl
[
url :endpoint
type :POST
parameters:count_params
connection:"zoho_analytics_conn"
];
total_count = 0;
// First try KV shape: {"data":[{"total_count":"10398"}]}
if(count_resp != null && count_resp.containsKey("data") && count_resp.get("data") != null && count_resp.get("data").size() > 0)
{
tc_raw = count_resp.get("data").get(0).get("total_count");
if(tc_raw != null)
{
total_count = tc_raw.toLong();
}
}
else
{
// Fallback to rows shape:
// {"response":{"result":{"column_order":["total_count"],"rows":[["10398"]]}}}
if(count_resp != null && count_resp.containsKey("response"))
{
resp_obj = count_resp.get("response");
if(resp_obj != null && resp_obj.containsKey("result"))
{
result_obj = resp_obj.get("result");
if(result_obj != null && result_obj.containsKey("rows"))
{
rows_list = result_obj.get("rows");
if(rows_list != null && rows_list.size() > 0)
{
first_row = rows_list.get(0);
// rows are arrays, so first cell holds the count as string
if(first_row != null && first_row.size() > 0)
{
tc_raw2 = first_row.get(0);
if(tc_raw2 != null)
{
total_count = tc_raw2.toLong();
}
}
}
}
}
}
}
/***** === Step 2: Build list of page indexes (Deluge compliant, no while) === *****/
page_map = list();
num_pages = (total_count / PAGE_SIZE).toLong();
if(total_count % PAGE_SIZE > 0)
{
num_pages = num_pages + 1;
}
// use nested for-each loops over a fixed dummy list to reach num_pages
dummy = list();
for each  d in {"a","b","c","d","e","f","g","h","i","j"}
{
// outer loop (10×)
for each  e in {"1","2","3","4","5","6","7","8","9","10"}
{
// inner loop (10×)
if(page_map.size() < num_pages)
{
page_map.add(page_map.size());
}
}
}
/***** === Step 3: For each page, fetch candidates and pick a batch winner via OpenAI === *****/
batch_winners = list();
for each  p in page_map
{
offset_val = p * PAGE_SIZE;
sql_batch = "select \"State\",\"School Name\",\"NCES School ID\",\"Zip\"" + "from \"" + view_name + "\" where \"State\"='" + state_esc + "' " + "limit " + PAGE_SIZE.toString() + " offset " + offset_val.toString();
params = Map();
params.put("ZOHO_ACTION","EXPORT");
params.put("ZOHO_OUTPUT_FORMAT","JSON");
params.put("ZOHO_API_VERSION","1.0");
params.put("KEY_VALUE_FORMAT","true");
params.put("ZOHO_SQLQUERY",sql_batch);
count_params.put("ZOHO_API_VERSION","1.0");
resp_batch = invokeurl
[
url :endpoint
type :POST
parameters:params
connection:"zoho_analytics_conn"
];
/***** Parse candidates safely no matter the response shape *****/
candidates = list();
if(resp_batch != null)
{
// Case 1: Key-value format (normal Zoho Analytics JSON)
if(resp_batch.containsKey("data") && resp_batch.get("data") != null)
{
candidates = resp_batch.get("data");
}
// Case 2: Nested "response" > "result" > "rows" format
else if(resp_batch.containsKey("response"))
{
resp_obj = resp_batch.get("response");
if(resp_obj != null && resp_obj.containsKey("result"))
{
result_obj = resp_obj.get("result");
if(result_obj != null && result_obj.containsKey("rows"))
{
rows_list = result_obj.get("rows");
// convert matrix rows into list of maps for consistency
for each  row_item in rows_list
{
row_map = Map();
// optional: if you have column_order, map by index
if(result_obj.containsKey("column_order"))
{
cols = result_obj.get("column_order");
idx = 0;
for each  col in cols
{
if(row_item.size() > idx)
{
row_map.put(col,row_item.get(idx));
}
idx = idx + 1;
}
}
candidates.add(row_map);
}
}
}
}
}
if(candidates.isEmpty())
{
info "No candidates found for this page (state=" + state_input + ")";
continue;
}
/***** Build compact OpenAI prompt for this batch *****/
cand_lines = "";
for each  c in candidates
{
id_short = ifnull(c.get("NCES School ID"),"");
name_short = ifnull(c.get("School Name"),"");
if(name_short != null && name_short.length() > 60)
{
name_short = name_short.substring(0,60);
}
zip_short = ifnull(c.get("Zip"),"");
if(zip_short != null && zip_short.length() > 10)
{
zip_short = zip_short.substring(0,10);
}
delimiter = "###";
// define this once before the loop if not already defined
record_sep = " || ";
// separates candidate rows, readable and single-line
cand_lines = cand_lines + id_short + "|" + name_short + "|" + zip_short + record_sep;
}
// === Build simplified OpenAI request (no line breaks) ===
prompt = "TARGET=" + target_name + "|" + zip_input + delimiter + "CANDIDATES=" + cand_lines + delimiter + "Return ONLY JSON {\"nces_school_id\": string|null, \"confidence\": number}";
messages = List();
messages.add({"role":"system","content":"Match the user-entered school to the best NCES candidate using NAME similarity and ZIP proximity. The delimiter is " + delimiter + "."});
messages.add({"role":"user","content":prompt});
req_body = Map();
req_body.put("model","gpt-4o-mini");
req_body.put("temperature",0);
req_body.put("messages",messages);
ai_resp = invokeurl
[
url :"https://api.openai.com/v1/chat/completions"
type :POST
parameters:req_body.toString()
connection:"openai_custom"
];
// ========== Step 4: Inspect result ==========
best_id = "";
best_conf = 0.0;
raw_content = ai_resp.get("choices").get(0).get("message").get("content");
// Remove markdown fences if present
cleaned = raw_content.replaceAll("(?s)```json|```","").trim();
parsed = cleaned.toMap();
school_id = parsed.get("nces_school_id");
confidence = parsed.get("confidence");
for each  c in candidates
{
if(c.get("NCES School ID") == school_id)
{
if(confidence > 0.8)
{
//do not put low-confidence candidates in the winner batch
c.put("confidence",confidence);
batch_winners.add(c);
break;
}
}
}
}
/***** === Step 4: Final round — pick overall best among batch winners === *****/
if(batch_winners.size() == 0)
{
update_map = Map();
update_map.put("NCES_School_ID",null);
update_map.put("Country","");
update_map.put("State",school_state);
zoho.crm.updateRecord("Schools",st_school_id,update_map);
info "No candidates found for state=" + state_input;
}
winner_lines = "";
for each  w in batch_winners
{
id_short = ifnull(w.get("NCES School ID"),"");
name_short = ifnull(w.get("School Name"),"");
if(name_short != null && name_short.length() > 60)
{
name_short = name_short.substring(0,60);
}
zip_short = ifnull(w.get("Zip"),"");
if(zip_short != null && zip_short.length() > 10)
{
zip_short = zip_short.substring(0,10);
}
delimiter = "###";
// define this once before the loop if not already defined
record_sep = " || ";
// separates candidate rows, readable and single-line
winner_lines = winner_lines + id_short + "|" + name_short + "|" + zip_short + record_sep;
}
// === Build simplified OpenAI request (no line breaks) ===
prompt = "TARGET=" + target_name + "|" + zip_input + delimiter + "CANDIDATES=" + winner_lines + delimiter + "Return ONLY JSON {\"nces_school_id\": string|null, \"confidence\": number}";
messages = List();
messages.add({"role":"system","content":"Match the user-entered school to the best NCES candidate using NAME similarity and ZIP proximity. The delimiter is " + delimiter + "."});
messages.add({"role":"user","content":prompt});
req_body = Map();
req_body.put("model","gpt-4o-mini");
req_body.put("temperature",0);
req_body.put("messages",messages);
final_ai = invokeurl
[
url :"https://api.openai.com/v1/chat/completions"
type :POST
parameters:req_body.toString()
connection:"openai_custom"
];
selected_nces = "";
confidence = 0.0;
contentText = final_ai.get("choices").get(0).get("message").get("content");
// Step 2: Sanitize it — remove code block markers and trim spaces/newlines
cleanText = contentText.replaceAll("```json","");
cleanText = cleanText.replaceAll("```","");
cleanText = cleanText.trim();
// Step 3: Parse the cleaned string as JSON
contentJSON = cleanText.toMap();
// Step 4: Extract the NCES/NCAS ID
selected_nces = contentJSON.get("nces_school_id");
/***** === Step 5: Find selected record and update CRM (unchanged) === *****/
/***** === Step 2: Fetch single row by NCES School ID === *****/
row_sql = "select \"NCES School ID\", \"Website\", \"Address\", \"Address 2\", \"City\", \"State\", \"Zip\", \"Phone\", \"Grade Level\" " + "from \"" + view_name + "\" " + "where \"NCES School ID\" = '" + selected_nces + "' " + "limit 1";
row_params = Map();
row_params.put("ZOHO_ACTION","EXPORT");
row_params.put("ZOHO_OUTPUT_FORMAT","JSON");
row_params.put("ZOHO_SQLQUERY",row_sql);
row_params.put("ZOHO_API_VERSION","1.0");
row_resp = invokeurl
[
url :endpoint
type :POST
parameters:row_params
connection:"zoho_analytics_conn"
];
/***** === Step 3: Parse response and assign variables === *****/
nces_id_final = "";
Website_final = "";
Address_final = "";
Address2_final = "";
City_final = "";
State_final = "";
Zip_final = "";
Phone_final = "";
Grade_final = "";
// First check for JSON KV structure
if(row_resp != null && row_resp.containsKey("data") && row_resp.get("data") != null && row_resp.get("data").size() > 0)
{
row_data = row_resp.get("data").get(0);
nces_id_final = selected_nces;
Website_final = ifnull(row_data.get("Website"),"");
Address_final = ifnull(row_data.get("Address"),"");
Address2_final = ifnull(row_data.get("Address 2"),"");
City_final = ifnull(row_data.get("City"),"");
State_final = ifnull(row_data.get("State"),"");
Zip_final = ifnull(row_data.get("Zip"),"");
Phone_final = ifnull(row_data.get("Phone"),"");
Grade_final = ifnull(row_data.get("Grade Level"),"");
}
else
{
// Fallback for "rows" format
if(row_resp != null && row_resp.containsKey("response"))
{
resp_obj = row_resp.get("response");
if(resp_obj != null && resp_obj.containsKey("result"))
{
result_obj = resp_obj.get("result");
if(result_obj != null && result_obj.containsKey("rows"))
{
rows_list = result_obj.get("rows");
if(rows_list != null && rows_list.size() > 0)
{
first_row = rows_list.get(0);
if(first_row != null && first_row.size() >= 9)
{
nces_id_final = ifnull(first_row.get(0),"");
Website_final = ifnull(first_row.get(1),"");
Address_final = ifnull(first_row.get(2),"");
Address2_final = ifnull(first_row.get(3),"");
City_final = ifnull(first_row.get(4),"");
State_final = ifnull(first_row.get(5),"");
Zip_final = ifnull(first_row.get(6),"");
Phone_final = ifnull(first_row.get(7),"");
Grade_final = ifnull(first_row.get(8),"");
}
}
}
}
}
}
country = "USA";
if(isNull(State_final))
{
country = "";
}
update_map = Map();
update_map.put("NCES_School_ID",nces_id_final);
update_map.put("School_Website",Website_final);
update_map.put("Address",Address_final);
update_map.put("Address_2",Address2_final);
update_map.put("City",City_final);
update_map.put("State",State_final);
update_map.put("Zip",Zip_final);
update_map.put("School_Phone",Phone_final);
update_map.put("Grade_Level",Grade_final);
update_map.put("Country",country);
update_rec = zoho.crm.updateRecord("Schools",st_school_id,update_map);
info st_school_id + " Updated";
/***** === Diagnostics === *****/
diag = Map();
diag.put("school_id",st_school_id);
diag.put("selected_nces_school_id",nces_id_final);
diag.put("model_confidence",confidence);
used_fallback = false;
if(selected_nces == "" || selected_nces == null)
{
used_fallback = true;
}
diag.put("used_fallback",used_fallback);
return diag.toString();
}
    • Sticky Posts

    • Kaizen #222 - Client Script Support for Notes Related List

      Hello everyone! Welcome to another week of Kaizen. The final Kaizen post of the year 2025 is here! With the new Client Script support for the Notes Related List, you can validate, enrich, and manage notes across modules. In this post, we’ll explore how
    • Kaizen #217 - Actions APIs : Tasks

      Welcome to another week of Kaizen! In last week's post we discussed Email Notifications APIs which act as the link between your Workflow automations and you. We have discussed how Zylker Cloud Services uses Email Notifications API in their custom dashboard.
    • Kaizen #216 - Actions APIs : Email Notifications

      Welcome to another week of Kaizen! For the last three weeks, we have been discussing Zylker's workflows. We successfully updated a dormant workflow, built a new one from the ground up and more. But our work is not finished—these automated processes are
    • Kaizen #152 - Client Script Support for the new Canvas Record Forms

      Hello everyone! Have you ever wanted to trigger actions on click of a canvas button, icon, or text mandatory forms in Create/Edit and Clone Pages? Have you ever wanted to control how elements behave on the new Canvas Record Forms? This can be achieved
    • Kaizen #142: How to Navigate to Another Page in Zoho CRM using Client Script

      Hello everyone! Welcome back to another exciting Kaizen post. In this post, let us see how you can you navigate to different Pages using Client Script. In this Kaizen post, Need to Navigate to different Pages Client Script ZDKs related to navigation A.
    • Recent Topics

    • Forwarder

      Hi, I tried to add a forwarder from which emails are sent to my main zoho account email . However, it asks me for a code that should be received at the forwarder email, which is still not activated to send to my zoho emial account. So how can I get the
    • No chat option

      Chat option is not supported.
    • Direct “Add to Google Calendar” Option in Zoho Meeting

      Hello Zoho Meeting Team, Hope you are doing well. We would like to request an enhancement related to the “Add to Calendar” functionality in Zoho Meeting. Currently, when we open Zoho Meeting and view our meetings under My Calendar, there is an Add to
    • Default Tagging on API-generated Transactions

      If one assigns tags to an Item or Customer, those tags get auto-populated in each line item of an Invoice or Sales Order when one creates those documents. However, if one creates the Sales Order or Invoice via the API (either directly coding or using
    • DKIM cannot be enabled for the domain as no verified default selector present

      Hi Support Team, For Domain DKIM record trying to enable status. but showing error "DKIM cannot be enabled for the domain as no verified default selector present" So, please resolve the issue. Thank you.
    • unable to send message reason 554 5.1.8 Email outgoing blocked

      unable to send message reason 554 5.1.8 Email outgoing blocked
    • I can't log in to my account on Thunderbird

      I've just had to rebuild my PC (calamitous mess from Microsoft with Win10/Win 11 'upgrade' - they confirmed I had to start with a new build). I have used Zoho mail for years via Mozilla Thunderbird, but now I've had to download the latest version of TBird,
    • Should I Use DMARC?

      When I configure Zoho Mail's DMARC settings, it's mandatory to fill in the RUA and RUF (Aggregate notification email address*, Forensic notification email address*) addresses. When we enter an email address in these fields, we receive reports from the
    • Introducing Profile Summary: Faster Candidate Insights with Zia

      We’re excited to launch Profile Summary, a powerful new feature in Zoho Recruit that transforms how you review candidate profiles. What used to take minutes of resume scanning can now be assessed in seconds—thanks to Zia. A Quick Example Say you’re hiring
    • Books API Receiving an Error that Doesn't Make Sense when Creating Credit Note - trying to use 'ignore_auto_number_generation' argument

      Hello, I'm working on a newly created routine and I'm getting an error that doesn't make sense when trying to create a new Credit Note. Here is my POST request. Endpoint: https://www.zohoapis.com/books/v3/creditnotes?organization_id=########## Body:     {
    • How to move emails to Shared Mailbox?

      Hello, I created a Shred Mailbox instead of using a distribution group. But I cannot move previous emails to certain shared mailbox. Is it possible move some emails from inbox to shared mailbox?
    • Collaboration with free plan user.

      Hello. Do both users need to be on Pro plan to collaborate? Or can a Pro user share a note with a free plan user with the ability to edit?
    • Connection to other user

      Zoho Cliq handles sharing of Custom OAuth Connections that require individual user logins.
    • In arattai received message can't be deleted

      The issue has been noticed in following: arattai app (Android) arattai app (Window) arattai web While the message posted by me may be deleted, the ones received from others can't be. The item <Delete> change to <Report> when the message is a received
    • Analytics Portal

      I have the "standard plan" and want to explore the portal option; I activated the 15-day trial but do not see the pricing for the add-on. How can I get the price under "Upgrade add-ons." Thanks Rudy
    • Can I filter a Lookup field to only show related records from another Lookup in Zoho CRM?

      In our Leads module, we have two Lookup fields: Recruitment Agency – the agency that the lead came from Recruiter – the individual contact from that agency who sent us the lead Both fields link correctly to their respective records in CRM. However, our
    • Zoho Books API invoice email bouncing with 'relaying-issues' error

      I have waited over 30 days for zoho books uk to assist with the following and i have had no replies or tickets erronously closed. The service has been terrible - very unlike zoho! So i am raising this here hoping that a community member can assist: Hello,
    • How do I filter contacts by account parameters?

      Need to filter a contact view according to account parameter, eg account type. Without this filter users are overwhelmed with irrelevant contacts. Workaround is to create a custom 'Contact Type' field but this unbearable duplicity as the information already
    • Zoho Writer to Zoho Sign Template Misalignment – Request for Community

      We are currently facing a critical issue impacting our live business operations due to a misalignment problem between Zoho Writer templates and Zoho Sign output. Issue Summary: We have an automated workflow in Zoho CRM using Deluge scripts that generates
    • Why can't we change the Account type from an Expense to an Asset?

      Like the question. Why in QuickBooks for example if I mistakenly created an account as an expenses and I already captured information in those accounts, I can just change the account type from expense to asset
    • Account blocked

      Yesterday I got my Zeptomail account blocked due to too many hard bounces. My account is used exclusively for sending transactional emails (eg. your order has been shipped, a form has been filled, etc) and the sudden blocking impacted hundreds of websites
    • Migration Tool Download

      Since apparently you have to ask for the migration tool to download (why?), I need the download for the migration tool for exchange servers. Please forward link, thanks.
    • IF Formula

      Hi, I'm having trouble setting up a custom formula in a field. Can you help me with it? The formula should do the following: If the created date is less or equal to 30 days the field should display a string New in pieline or Exisitng pipeline if above
    • Autorespond to one specific sender

      Is there any way to create a rule or filter that sends an automatic reply to messages from one specific email address?  I really need to set up something like a "vacation response" but only for one "received from" address.
    • View comprehensive logs of all actions in Custom Module History

      Hello everyone, We are happy to announce our new feature, Detail View in Custom Module History, which enhances visibility, control and accountability over your records. Users can now access a detailed timeline of every action that has been performed on
    • Track ZohoForm Conversion using Postmessage event

      Hi, I’ve been using a third-party lead tracking tool to capture leads from my website along with their source. Earlier, with the HubSpot form, the third-party script was able to detect the postMessage event that iframe forms typically send back to the
    • Email task creator when task is updated/marked complete

      I am looking for a way to notify the creator of a task in zoho todo when - Task is updated Task is closed Comments entered 1 and 2 are critical, and I cannot find a zoho flow to do this. There is no way that as a manager I will know when someone has completed
    • Email Recall Feature In Zoho Mail Which Should Also Work For Outside Organisation Members

      Add a feature to recall or undo sending an email within a configurable short time window (e.g., 30 seconds to 2 minutes) after hitting send, similar to Gmail’s undo send. Currently the sent email can not be recall If the recipient is not from within your
    • how to treat a same person as customer and vendor in zoho

      hi team, in my company, few persons acting as creditors as well as debtors (which means sometimes we pay them... some times we paid by them). in that case i would like to maintain a same ledger for that person.in zoho books it is treating creditor and
    • How to implement calculating average value of averaged values?

      Hi, I'm trying to implement a formula in my layout for a module that calculates the average of 2 averaged values, but I can't do so using the formula custom field. To calculate the 2 averaged values, I could use the formula custom field, but in the custom
    • Zoho Recruit update published job boards

      If we have a job thats already posted on several different job boards and we edit this job in zoho recruit (e.g. the description of the job), does this then automatically update this new information to all the published job boards?  If not, how does the
    • Narrative 14: The magic bazaar of Desk

      Behind the scenes of a successful ticketing system: BTS Series Narrative 14: The magic bazaar of Desk Marketplace is a centralized platform where users can discover Zoho and third-party applications that can be integrated with their Desk account to facilitate
    • Collections Management: #2 Late Payment Automation

      "Sir, I'll process the payment by evening, please don't apply any late payment charges", the customer said while arranging papers on his desk. Sanjay stood there with a tired smile. He had already visited twice that week. Payment collection was one thing.
    • Create a table in the layout section of modules

      Dear Sirs, I would like to know whether is possible to create a table under new fields in layouts section of modules. In fact in this section there are single line, multi line, pick list, multi-select, date, formula etc. but I am unable to add a table
    • Nimble enhancements to WhatsApp for Business integration in Zoho CRM: Enjoy context and clarity in business messaging

      Dear Customers, We hope you're well! WhatsApp for business is a renowned business messaging platform that takes your business closer to your customers; it gives your business the power of personalized outreach. Using the WhatsApp for Business integration
    • Power of Automation :: Automatic Task Status Handling for Users

      Hello Everyone, A custom function is a software code that can be used to automate a process and this allows you to automate a notification, call a webhook, or perform logic immediately after a workflow rule is triggered. This feature helps to automate
    • Question - why no way to input a 'tool description' and 'tree of 'tools'

      Every business is different, with different business processes. To be truly useful Zoho MCP needs to have user editable tool descriptions (or ruleset) and a 'tool tree' so that the LLM is context aware when being used. For example, the tool description
    • Develop Zoho Meeting as a Full Native Application (Not a Browser Wrapper)

      Hello Zoho Meeting Team, Hope you are doing well. We would like to suggest an important improvement regarding the Zoho Meeting desktop application. At the moment, the Zoho Meeting app feels more like a mini browser window or an iframe that loads the web
    • Can I create a custom function for chart of accounts?

      I'm trying to add a custom function that should run whenever a record in the Chart of Accounts module is edited, but on the form for creating a new function, the module dropdown does not include the chart of accounts as an option.
    • billing

      hi, I am being billed $12/year, and I can't remember why. My User ID is 691273115 Thanks for your help, --Kitty Pearl
    • Next Page