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 #198: Using Client Script for Custom Validation in Blueprint

      Nearing 200th Kaizen Post – 1 More to the Big Two-Oh-Oh! Do you have any questions, suggestions, or topics you would like us to cover in future posts? Your insights and suggestions help us shape future content and make this series better for everyone.
    • Kaizen #226: Using ZRC in Client Script

      Hello everyone! Welcome to another week of Kaizen. In today's post, lets see what is ZRC (Zoho Request Client) and how we can use ZRC methods in Client Script to get inputs from a Salesperson and update the Lead status with a single button click. In this
    • Kaizen #222 - Client Script Support for Notes Related List

      Hello everyone! Welcome to another week of Kaizen. The final Kaizen post of the year 2025 is here! With the new Client Script support for the Notes Related List, you can validate, enrich, and manage notes across modules. In this post, we’ll explore how
    • 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
    • Recent Topics

    • I can not save new invoice

      Hello Now I am trying to save a new invoice but I can not save it because showing unpaid invoice warning which are not overdue. Please let me know how to skip unpaid invoice warning letter and save new invoice. Thank you
    • ADD CONDITIONS FOR FIELD IN ZOHO BOOKS TEMPLATE CUSTOMAZATION

      HELLO I WANT TO ADD CONDITIONS FOR FIELD IN ZOHO BOOKS TEMPLATE CUSTOMAZATION FOR SALES ORDER . I HAVE SET %StatusStamp% IF APPROVAL I WANT THAT TEXT TO BE DISPLAYED WITH GREEN COLOR OTHERWISE OF OTHERR STATUS RED COLOR AS SHOWN IN CODE BELOW . BUT IT
    • Accounting on the Go Series-55: Seamlessly Add New Vendors While Creating Transactions from Scanned Documents

      Hi there! We’ve made handling documents and vendors in Zoho Books even simpler. Now, when you upload a document and scan it, if the app detects a vendor that isn’t already in your organization, you don’t have to leave the page to add them manually. With
    • Accounting on the Go Series-57: Effortlessly Add and Manage Bank Accounts from the Zoho Books Mobile App

      Hi all, Great news for our users in the US and Canada! Managing your finances just got a whole lot easier. Zoho Books has always made it seamless to integrate bank accounts and fetch feeds automatically. Now, we’re taking it up a notch—directly from the
    • Accounting on the Go Series:58-Effortless Compliance: Download XML for Invoices & Credit Notes on Mobile

      Hi there! In Mexico, XML files are crucial for electronic invoicing and fulfilling SAT (Tax Administration Service) requirements. These files ensure your transactions are accurately recorded and tax-compliant. Now, you don’t need to rely on the web app
    • Auto Generated Invoice number YEAR

      Auto Generated Invoice number shows transaction year as 25 even though it's 24 still.
    • Books generiert keine valide XRechnung

      Hallo zusammen, ich möchte hier ein Problem ansprechen, das mir aktuell bei der Nutzung von Books erhebliche Schwierigkeiten bereitet, und hoffe auf Austausch oder Lösungsansätze von anderen Nutzern. Bei der Erstellung von XRechnungen mit Books treten
    • WHEN UPDATE ORGANIZATION INFO OLD INVOICES ALSO CHANGE INVOICING DATA

      Hi We have updated our tax information because we have become a company, up until now we were an individual. The problem is that when updating the data in the zoho books profile all the old invoices change their tax information as well. Is there a way
    • Invoice import error - duplicate customer name column - there are no duplicates

      It is not allowing the importing of any rows because of a duplicate customer name problem, but there are no duplicates in the custoemr name row. Has anyone dealt with this issue before?
    • [WEBINAR][Feb 2025] Automate your entire financial operations from receipts to reconciliation with Zoho Books & Zoho Expense integration

      Hello there, We are hosting a free, live webinar on the importance of travel and expense management solutions for businesses, and how Zoho Expense automatically syncs with Zoho Books to simplify your accounting even further. The webinar is on February
    • Customize Layout

      I am using "Customize Layot" for customize Quotation template but I try to add logo into the header by "%ScaledLogoImage%" code but dont add logo into header. what is problem?
    • Problem - cant add Users (i.e. Zoho one / CRM Users) to BCC or CC in email, i.e. Sales orders or Retainers

      I can go to zoho books email templates, and select any email template, and automatically include any Zoho One user, i.e. member of staff. However in the context of sending an email, it will not let us add a member of staff from the user list, instead
    • UK MTD ITSA

      UK Making Tax Digital for Income Tax I have had notice this is to apply from April 2026. What is Zoho doing about this? I will need to start planning to implement this in the next months so need an update as to what I will and will not be able to do in
    • Zoho Books Roadshows are back in the UAE!

      Hello there, Business owners and accounting professionals of the UAE, we’re coming to your cities! FTA accredited Zoho Books is now officially one of the Digital Tax Integrators in the UAE. With the newly launched direct VAT filing capabilities, we're
    • New user After moving over from QBO

      New user observations/suggestions. QBO took away a lot of features I was used to with the desktop version. Chaos ensued. Zoho Books has a lot of what I was used to and a bit more. Good deal Some things I have run into and suggest some upgrades. 1: The
    • Sole Trader - Financial Advisor (Appointed Representative) - Paid via Capital Account but no Invoicing...

      Hi. I'm about to venture into a new business after 12 months of intensive learning/exams. A little chuffed if I may say so especially at 52! I really like the look of ZoHo Books for my modest enterprise but I'm in need of some guidance, please. My services
    • Multi-Unit Inventory with Flexible Unit Selection (Purchase in One Unit, Sell in Another)

      We need multi-unit inventory management in Zoho Books with the flexibility to choose units (e.g., Box or Piece) at the time of purchase or sale. For example, if 1 Box = 10 Pieces, we should be able to record purchases in Boxes but sell either in Boxes
    • Disputed Purchase Invoices

      We have recently moved to Zoho Books from Sage. In Sage we were able to post a purchase/vendor invoice but mark it as on dispute. This would usually be a pricing query or if something was damaged. It would show in their ledger, so we could agree their
    • No TDS Deduction

      In some of our case, where we are reselling items at the same rate we purchased. In this scenario, Indian IT Law has a provision to request customer not to deduct TDS if the transaction value is same. TDS is paid by us (intermediary reseller) before we
    • CBSA - GST CHARGES on imports

      Hi there, We have a questions about landed cost categorization. We received a shipment from overseas. CBSA invoiced us for the GST on the items. Now we entered the CBSA-GST as a separate bill and attached it as landed cost to the main invoice based on
    • Zoho Books

      How do I manually insert opening balance?
    • Sales order & purchase order item links for item details

      This is fantastic for checking lots of things, I use it a lot. It would be great to see it extended to invoices & bills On another note, may as well throw in my favourite whinge ..... Wish you guys would get the PO receive differences sorted urgently,
    • Bank charges are applied. Please select a bank account.

      Hello, I'm trying to add bank charges to a customer payment, but I get the error message "Bank charges are applied. Please select a bank account." I found this old thread, where it says that I need to "select a Bank account for the 'Deposit To' dropdown
    • How to add receipts

      How to add receipts
    • Support for auto-upgrade in TrueSync (for Windows)

      WorkDrive TrueSync app now supports auto-upgrading to the latest version for Windows OS. You must manually download and install the TrueSync app version 3.4.0 to avail this feature. Download the latest TrueSync app for Windows (version 3.4.0) Supported
    • WorkDrive API Documentation

      WorkDrive provides users and developers an extensive set of APIs to help integrate functionalities of Zoho WorkDrive with other Zoho applications and third-party tools. We have published the official WorkDrive API Documentation page for all external users.
    • March 15, 2023: Zoho Docs is discontinued

      As of today (March 15, 2023) Zoho Docs is discontinued for all users. We would like to thank our customers for trusting us for so many years! Going forward, we're confident you'll enjoy using Zoho WorkDrive for all your advanced file management and collaboration
    • Introducing WorkDrive 4.0: Enhanced productivity. Advanced data administration. (Phase 1)

      Hello All, We're excited to share the release of WorkDrive 4.0, which includes important new features and enhancements focused primarily on productivity, secure collaboration, data administration, integrations, and user experience. Read the official announcement
    • External download link limit

      Can You please help us to understand this For Zoho WorkDrive external users, the download limit is a maximum of 5 GB total download size and a maximum of 50 first-level files and folders What is the meaning of first level? We are using these files in
    • Dynamically catching new file creations

      I have a team folder with many subfolders, and in those folders we add new documents all the time. I'd like to have a workflow or script to notify me (and then take other actions) when a file is added anywhere in that structure that ends in "summary.txt".
    • Rotate an Image in Workdrive Image Editor

      I don't know if I'm just missing something, but my team needs a way to rotate images in Workdrive and save them at that new orientation. For example one of our ground crew members will take photos of job sites vertically (9:16) on his phone and upload
    • Workflow workdrive rollout

      Hi! When will workflow be rolled out to all users? Thanks.
    • Creating and managing a Team Folder using WorkDrive TrueSync

      Hello everyone, Are you tired of constantly switching between your Desktop TrueSync app and the WorkDrive web app to create and manage Team Folders? We’ve made things easier for you. You can now create and manage Team Folders directly within the TrueSync
    • Edit images seamlessly with WorkDrive's built-in Image Editor

      Are you tired of switching between multiple tools just to make simple edits to your images? We understand the hassle, which is why Zoho WorkDrive now comes with a built-in image editing tool, powered by Zoho Annotator. This tool allows you to edit images
    • Supercharge your email workflow with WorkDrive's add-in for Microsoft Outlook

      Consider this: You’re handling a critical project, and your inbox is packed with important attachments, email threads, and client communications. The back-and-forth routine of downloading files to your computer, uploading them to WorkDrive, and manually
    • Secure and promote your content with Custom Watermarking

      Imagine this: You’re a professional photographer who regularly shares your work online with potential clients and collaborators. Recently, you notice that some of your images have been reposted without any credit or permission. This not only impacts your
    • Join us in Singapore for the Zoho WorkDrive User Group meetup!

      Hello, everyone! Exciting news! We'll be hosting an upcoming Zoho WorkDrive user group meetup in the beautiful city of Singapore this November. At this Zoho User Group meetup, we'll guide you through ways to use WorkDrive as a platform and build custom
    • WorkDrive TrueSync now supports ARM64-based Windows devices!

      We’re excited to announce that the Zoho WorkDrive TrueSync app now fully supports Windows devices with ARM64 architecture! Whether you're working on an ARM-based device or an x64 processor, you can now enjoy the same seamless file synchronization experience
    • Option to Disable Download for Documents Shared via Permalink

      Dear Zoho Writer Team, Currently, when sharing a Writer document using the regular permalink (Collaborators with external users), there is no option to restrict the ability to download the document. While the external share link allows such restrictions,
    • How to Download a File from Zoho WorkDrive Using a Public Link

      How to Download a File from Zoho WorkDrive Using a Public Link If you're working with Zoho WorkDrive and want to download a file using a public link, here's a simple method to do so using API or a basic script. This approach helps developers or teams
    • Next Page