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();
}

    Nederlandse Hulpbronnen


      • Recent Topics

      • Direct Integration Between Zoho Cliq Meetings and Google Calendar

        Dear Zoho Team, We’d like to submit the following feature request based on our current use case and the challenges we’re facing: 🎯 Feature Request: Enable meetings scheduled in Zoho Cliq to be automatically added to the host's Google Calendar, not just
      • Zoho sheet

        Unable to share zoho sheet with anyone on internet with editer option only view option is show
      • Mail and OS

        Jai Hind! Zoho is doing good by creating good software (made in india) on par with other tech giants. 🥰 Suggestion: 1. Whenever we sign up on zoho mail its asking for other mail id. It shouldn't be like that. You should ask general details of a user
      • Personal account created under org account

        Hi there, I am Jayesh. We are using ME Central, and we have an account by the email ID soc@kissht.com.. Now I have created a personal account., jayesh.auti@zohomail.in, accidentally. Can you help me to remove this jayesh.auti@zohomail.in from my organization
      • Add another account

        How to add another mail account to my zoho mail.
      • Recover deleted user

        Hi by mistake i have deleted an added user and his email associated. Please help me recover it thank you.
      • No connection to the server

        Hello! I can't add a new email address to my mailbox because your server is rejecting me. Please help. I took and added a screenshot of this problem Marek Olbrys
      • URGENT: Business Email Disruption – SMTP Authentication Failed

        Dear Zoho Support, I am writing to escalate a critical issue with my business email account: 📧 marek@olbrys.de My domain olbrys.de is fully verified in Zoho (MX, SPF, DKIM, DMARC all valid – green status). I am using the correct configuration: smtp.zoho.eu
      • Emails missing from desktop but visible on phone

        Subject says it all. Windows 11 laptop. Apple phone. all systems up to date.
      • Website Hosting

        Hello, I want to host my domain on Hostinger, and I want my emails to run through Zoho Mail. Please provide me with the SPF record, MX record (Type: TXT), and A record, so that I don’t face any issues with my emails. My website is on Hostinger hosting,
      • Can not search zoho mail after update V.1.7.0

        i can not search mail on to and cc box from attached picture and then search contacts box can't click or use anything. include replay mail too.
      • Urgent Security Feature Request – Add MFA to Zoho Projects Client Portal Hello Zoho Projects Team,

        Hello Zoho Projects Team, We hope you are doing well. We would like to submit an urgent security enhancement request regarding the Zoho Projects Client Portal. At this time, as far as we are aware, there is no Multi-Factor Authentication (MFA) available
      • How to retreive the "To be received" value of an Item displayed in Zoho inventory.

        Hi everyone, We have our own Deluge code to generate a PO according to taget quantity and box quantity, pretty usefull and powerful! However, we want to reduce our quantity to order according to "To be received" variable. Seems like this might not even
      • Payment on a past due balance

        Scenario: Customer is past due on their account for 4 months. We suspend their billing in Zoho books. Customer finally logs into the portal and enters a new credit card. We associate that cardwith their subscription, which will permit the card to be used
      • Kaizen #211 - Answering your Questions | Using Canvas and Widgets to Tailor CRM for Mobile

        Howdy, tech wizards! We are back with the final post in addressing the queries you shared for our 200th milestone. This week, we are focusing on a couple of queries on Zoho CRM mobile configurations and custom payment gateway integration. 1. Mobile SDK
      • Remove "Invalid entries found. Rectify and submit again" modal

        Following up on a post from a few years back, but can the Zoho team consider either removing the 'Invalid entries found. Rectify and submit again' modal that displays for empty mandatory fields OR allow an admin to change it? I've built a custom error
      • No Functional Autosave or Manual Save Button

        Application : Zoho Notebook So I wanted to try Zoho Notebook(On Ubuntu) as an application, I installed the application and went solving my LeetCode problems visually(Drawing mode), at one point the app just stopped saving anything... Every time I tried
      • Cadence reports as front-end reports

        Hello everyone, We have built a cadence which is connected to the Leads module. There are 11 steps in total, 7 are automatic emails and 4 are tasks for the Lead owners. As admins, we have access to this (very nicely made) 'View Reports' tab where we can
      • Show elapsed time on the thank-you page?

        Is it possible to display the total time a user spent filling out a Zoho Form on the thank-you? I’d like to show the difference between the `form submission timestamp` and the `start time` (currently have a hidden Date-Time field set to autofill the date
      • Email Integration - Zoho CRM - OAuth and IMAP

        Hello, We are attempting to integrate our Microsoft 365 email with Zoho CRM. We are using the documentation at Email Configuration for IMAP and POP3 (zoho.com) We use Microsoft 365 and per their recommendations (and requirements) for secure email we have
      • I need to do crud with snippet html

        I need to implement a form with an improved user interface. I would like to use snippets to build a CRUD that allows me to create and update records. How could I achieve this using snippets?
      • Allow Stripe Credit Card and Stripe ACH payment methods to be enabled separately on an invoice.

        I need to be able to pick at the invoice level whether Stripe Credit Card and/or Stripe ACH payment methods are available. Currently, I'm not able to select from the two Stripe payment methods individually on an invoice. However, there are some larger
      • Meeting impossible to use when sharing screen

        he Meeting tool in Brazil is practically unusable when sharing anything, whether it’s a presentation or simple navigation. When accessed via Cliq, the situation gets even worse: even basic calls fail to work properly, constantly freezing. And as you are
      • Resume Harvester: New Enhancements for Faster Sourcing

        We’re excited to share a set of enhancements to Resume Harvester that make sourcing faster and more flexible. These updates help you cut down on repetitive steps, manage auto searches more efficiently, and review candidate profiles with ease. Why we built
      • Incorrect “correct” password on email client apple mail

        I have troubleshot this account several times. I have deleted and re added account. It keeps saying incorrect password. Can you check that it is not locked on your end?
      • Is it possible to lock editing subform rows?

        Ideally editing would only be locked after the form has been updated but I still want them to be able to add new subform records at any time and they should be able to delete rows from the subform. It is a named subform if that's relevant however the
      • "Spreadsheet Mode" for Fast Bulk Edits

        One of the challenges with using Zoho Inventory is when bulk edits need to be done via the UI, and each value that needs to be changed is different. A very common use case here is price changes. Often, a price increase will need to be implemented, and
      • What is the maximum file size of a video upload in Zoho chat?

        Can I upload a 20 mb video file and share it with my colleagues? 
      • Update a field in ALL all calls under a contact

        HI guys! I have written some deluge code to update a field in my calls after i have comepleted the call, i need this field to update in all my scheduled calls as well that are comeing up. I just cant seem to get it to work, i have put teh code below,
      • In place field editing for candidates

        Wondering about any insight/best practices for efficiently updating candidate records while reviewing them in a Job Opening pipeline. We can do in-field editing (e.g. update job title or City) only when we have the full candidate record open, however
      • Automatic Matching from Bank Statements / Feeds

        Is it possible to have transactions from a feed or bank statement automatically match when certain criteria are met? My use case, which is pretty broadly applicable, is e-commerce transactions for merchant services accounts (clearing accounts). In these
      • Verifying Zoho Mail Functionality After Switching DNS from Cloudflare to Hosting Provider

        I initially configured my domain's (https://roblaxmod.com/) email with Zoho Mail while using Cloudflare to manage my DNS records (MX, SPF, etc.). All services were working correctly. Recently, I have removed my site from Cloudflare and switched my domain's
      • Fat Download of Ulaa Browser

        I just observed that Ulaa Browser is offering an one-capsule big download. These days it is a custom to offer a small bootstrap downloader and based on user customization options an appropriate download completes. And this is particularly common with
      • Cancelled Transfer order problem

        Hello, We've canceled a transfer order, and we can't add the related items to a new Transfer Order. The system tells us that the bin doesn't have the required quantity, but when we check the item, it indicates that there are 2 units in the bin. It also
      • Zoho Creator customer portal limitation | Zoho One

        I'm asking you all for any feedback as to the logic or reasoning behind drastically limiting portal users when Zoho already meters based on number of records. I'm a single-seat, Zoho One Enterprise license holder. If my portal users are going to add records, wouldn't that increase revenue for Zoho as that is how Creator is monetized? Why limit my customer portal to only THREE external users when more users would equate to more records being entered into the database?!? (See help ticket reply below.)
      • Billing Management: #8 Usage Billing in Logistics & Delivery Services

        The logistics and delivery industry thrives on movement and precision. Every delivery completed, every kilometre driven, and every ton transported is a measurable activity. However, billing often lags behind. Many logistics companies still rely on fixed-rate
      • Zoho sheet for desktop

        Hi is zoho sheets available for desktop version for windows
      • Tags for New Tickets

        Hi there, When creating a new ticket, there is currently no way to choose a tag you would like to associate with the new ticket. Being able to associate a tag while creating a new ticket will be very beneficial as it will save time and flow well with
      • Zoho Desk: No Incoming email

        Is Zoho Desk services down? No incoming email reflect to desk tickets.
      • Mapping a new Ticket in Zoho Desk to an Account or Deal in Zoho CRM manually

        Is there any way for me to map an existing ticket in Zoho desk to an account or Deal within Zoho CRM? Sometimes people use different email to put in a ticket than the one that we have in the CRM, but it's still the same person. We would like to be able
      • Next Page