COQL API in Zoho CRM - Part I

COQL API in Zoho CRM - Part I

Hi everyone! Welcome back to another week of Kaizen

This week, we will discuss the COQL Queries in detail.

COQL (CRM Object Query Language) is a powerful query language based on SQL syntax that allows users to write their own queries and fetch records using module API names and field API names. In this post, we will discuss the operators supported by COQL in detail and also provide examples to help you understand better.  Please note that the information in the article holds true for version 4 of Zoho CRM APIs.

When should you use the Query API?

Use Query API when you want to query for a module's data and/or it's look up related data using various comparators, or for records that fall into a custom view without actually creating one. For example, if you want to query for all products in a specific price range, with a 5 star rating and sort the results by price, use the Query API. Similarly you can use Query API to query for records from cross-modules (linked via lookup field), such as filtering products based on the vendor's details. 

What types of queries are supported by COQL?

COQL supports only the SELECT query, which is used to select data from the CRM, based on the conditions specified by the clauses. 

Here is a sample query:
SELECT {field_api_names} FROM {module_api_name} WHERE {field_api_name} {comparator} {logical_operator} {value} ORDER BY {field_api_name} ASC/DESC LIMIT {limit} OFFSET {offset}

What are the clauses & aggregate functions supported by COQL?

WHERE - used to select records based on specific conditions.
FROM - specifies the module from which to fetch the records.
ORDER BY - used to sort the results in ascending or descending order.
LIMIT - used to limit the number of records returned by the query.
OFFSET - used to skip a specified number of records while retrieving the records.


{
 "select_query" : "select Last_Name, First_Name, Mobile, Final_Score from Leads where (Lead_Status = 'Not Contacted') ORDER BY Final_Score DESC LIMIT 5 OFFSET 10"
}


For example, the above query retrieves the Last_Name, First_Name, Mobile and Final_score of all Leads whose status equals 'Not Contacted'. The results will be sorted in descending order based on the Final_Score field, and only the 5 records after skipping the first 10 will be returned.

NOTE : You can also use the syntax "LIMIT offset, limit" to achieve the same result. For example :


{
 "select_query" : "select Last_Name, First_Name, Mobile, Final_Score from Leads where (Lead_Status = 'Not Contacted') ORDER BY Final_Score DESC LIMIT 5, 10"
}


Aggregate functions can perform calculations on a set of values and return a single value. 
SUM() - to get the sum of the values of an aggregate field in a module.
MAX() - to get the maximum value of an aggregate field.
MIN() - to get the minimum value of an aggregate field.
AVG() - to get the average value of the values of a field.
COUNT() - to get the number of records that satisfy the criteria.

Wildcard Character Support in COQL

In COQL queries, the only supported wildcard character is %. This % wildcard can be used with the like operator to achieve functionality similar to the contains, starts_with and ends_with operators. For instance, '%tech" queries for field values ending with tech, 'C%' queries for the values starting with C, and '%tech%' translates to contains 'tech'.

Supported field types and Comparators

The following table gives a gist of the field types whose data you can query for, and the comparators for each field type.
Field TypeComparators
Text and Picklist=, !=, like, not like, in, not in, is null, is not null
Lookup=, !=, in, not in, is null, is not null
Date, DateTime, Number, Currency=, !=, >=, >, <=, <, between, not between, in, not in, is null, is not null
Boolean=

Supported field types and Comparators

1) Text and Picklist Fields

Supported comparators : =, !=, like, not like, in, not in, is null, is not null. Please note that the like operator is used for starts_with, ends_with, contains, and not like operator is used for not contains

Sample Query 1: (=, like, in)

{
    "select_query": "SELECT First_Name, Last_Name FROM Leads WHERE (((Lead_Status = 'Pre-Qualified') and (Company like '%zylker%')) and Industry in ('Technology', 'ERP'))"
}

This SELECT query retrieves the First_Name and Last_Name of all Leads whose Lead_Status is Pre-QualifiedCompany contains zylker, and Industry is either Technology or ERP

Sample Query 2:(not in, like, not null)

{
"select_query": "SELECT First_Name, Last_Name FROM Leads WHERE (((Lead_Status not in ('Closed-Won', 'Closed-Lost')) and (Lead_Source like '%Web%')) and (Skype_ID is not null)) LIMIT 2"
}

This query will return the first name and last name of all leads whose lead status is not Closed-Won or Closed-Lost, whose Lead Source fields contains web, and whose Skype ID field is not empty.

Sample Query 3:( !=, not like, null)

{
    "select_query": "SELECT First_Name, Last_Name, Mobile FROM Leads WHERE (((Lead_Source != 'Webinar') and (City not like '%New York%')) and (Skype_ID is null))"
}

This query retrieves the first name, last name and mobile of leads where the lead source is not a webinar, the city is not New York, and the Skype ID field is empty or null.

2. Lookup Fields

=, !=, in, not in, is null, is not null are the supported comparators for lookup fields. If you want to get the name of the lookup field in the response, you must include the field API name in the query. Otherwise, the system will return only the ID of the field.

Sample Query 1: (=, not in, !=)

{
 "select_query": "select Last_Name, First_Name, Full_Name, Account_Name, Owner from Contacts where (((Account_Name.Account_Name != 'Zylker') and (Owner = 4876876000000327001)) and Vendor_Name.Vendor_Name not in ('Skytech','SR')) LIMIT 2"
}

This query retrieves the last name, first name, full name, account name, and owner of two contacts whose account name is not Zylker, whose owner ID is 4876876000000327001, and whose vendor name does not contain Skytech or SR.
Sample Response:
{
    "data": [
        {
            "First_Name": "John",
            "Full_Name": "John Wilson  ",
            "Owner": {
                "id": "4876876000000327001"
            },
            "Last_Name": "Wilson  ",
            "Account_Name": {
                "id": "4876876000000333089"
            },
            "id": "4876876000000333182"
        },
        {
            "First_Name": "Josephine",
            "Full_Name": "Josephine Darakjy",
            "Owner": {
                "id": "4876876000000327001"
            },
            "Last_Name": "Darakjy",
            "Account_Name": {
                "id": "4876876000000333090"
            },
            "id": "4876876000000333183"
        }
    ],
    "info": {
        "count": 2,
        "more_records": true
    }
}

In this query, the id of the account is returned but not the name since we have not specified the field API name in the query. To fetch the field name, specify the field API name in the query. Refer to the following sample query to know how.

Sample Query 2:  (in, is null, is not null)

{
    "select_query": "SELECT Deal_Name, Account_Name.Account_Name, Created_Time FROM Deals WHERE (((Account_Name.Account_Name in ('Grayson','Zylker')) and (Owner is not null)) and (Contact_Name is null)) ORDER BY Created_Time DESC LIMIT 2"
}

This query retrieves the Deal Name, Account Name, and Created Time of the 2 most recently created Deals whose Account Name contains Zylker or Grayson, and do not have a Contact Name associated with them but have a Deal Owner associated with them. The results will be ordered in descending order by the Created Time.
 
Sample Response:
{
    "data": [
        {
            "Deal_Name": "Westborne Deal",
            "Created_Time": "2023-04-06T10:04:02+05:30",
            "Account_Name.Account_Name": "Grayson",
            "id": "4876876000003548001"
        },
        {
            "Deal_Name": "Eastwing Deal",
            "Created_Time": "2023-04-05T19:10:55+05:30",
            "Account_Name.Account_Name": "Grayson",
            "id": "4876876000003526011"
        }
    ],
    "info": {
        "count": 2,
        "more_records": true
    }
}

In the same query, if you want to use the Account ID instead of the name, replace ((Account_Name.Account_Name in ('Grayson','Zylker')) with ((Account_Name in (4876876000001236083, 4876876000002799001)) to include the IDs instead of the field API names and the account names.
{
    "select_query": "SELECT Deal_Name, Account_Name.Account_Name, Created_Time FROM Deals WHERE (((Account_Name in (4876876000001236083, 4876876000002799001)) and (Owner is not null)) and (Contact_Name is null)) ORDER BY Created_Time DESC LIMIT 2"
}

3. Date, DateTime, Number, Currency Fields

=, !=, >=, >, <=, <, between, not between, in, not in, is null, is not null are the supported comparators for these fields.

Sample Query 1: (between, <, >)

{

    "select_query": "SELECT Deal_Name, Amount, Stage, Probability FROM Deals WHERE (((Closing_Date between '2023-01-01' and '2023-03-31') and (Probability < 99)) and (Amount > 10000))"

}

This query retrieves the deal name, amount, stage, and probability of all deals whose closing date is between January 1, 2023 and March 31, 2023, and whose probability is less than 99 and amount is greater than 10000.

Sample Response:
{
    "data": [
        {
            "Deal_Name": "Chapman Deal",
            "Amount": 2500000,
            "Probability": 97,
            "Stage": "Closed Won",
            "id": "4876876000003550011"
        }
    ],
    "info": {
        "count": 1,
        "more_records": false
    }
}

Sample Query 2: (<=, !=, >=)

{
    "select_query": "SELECT Product_Name, Qty_in_Stock, Vendor_Name, Cost_Price FROM Products WHERE (((Sales_End_Date <= '2023-04-30') and (Qty_in_Stock != 0)) and (Cost_Price >= 500))"
}

This query retrieves the product name, quantity in stock, vendor name, and cost price for all products whose sales end date is on or before April 30, 2023, whose quantity in stock is not zero, and whose cost price is greater than or equal to 500. Since Vendor_Name is a lookup field, only the ID will be returned in the response.
Sample Response
{
    "data": [
        {
            "Cost_Price": 2000,
            "Vendor_Name": {
                "id": "4876876000001039017"
            },
            "Product_Name": "Sigma",
            "Qty_in_Stock": 30,
            "id": "4876876000001036109"
        }
    ],
    "info": {
        "count": 1,
        "more_records": false
    }
}

Sample Query 3: (not between, is not, >)

{
    "select_query": "SELECT Last_Name, First_Name, Referred_By.Full_Name FROM Leads WHERE (((Final_Score not between 10 and 20) and (Annual_Revenue is not null)) and (No_of_Employees > 200)) LIMIT 1"
}

This COQL query selects the last name, first name, and the full name of the lead's referred by field, for one lead whose final score is not between 10 and 20annual revenue is not null and whose number of employees is greater than 200
Sample Response
{
    "data": [
        {
            "First_Name": "Chau",
            "Last_Name": "Kitzman",
            "id": "4876876000000333403",
            "Referred_By.Full_Name": "Simmons Truhlar"
        }
    ],
    "info": {
        "count": 1,
        "more_records": true
    }
}

Sample Query 4: (>, not in, =, is null)

{
   "select_query":"SELECT PO_Number, PO_Date, Status, Discount FROM Purchase_Orders WHERE (((PO_Date = '2023-04-06') and (Due_Date not in ('2023-04-10','2023-04-11', '2023-04-12'))) or ((Discount > 10) and (Requisition_No is null)))"
}

This query selects the PO_Number, PO_Date, Status, and Discount from the Purchase_Orders module where the PO_Date is equal to '2023-04-06' and Due_Date is not any of '2023-04-10', '2023-04-11', or '2023-04-12'; OR Discount is greater than 10 and Requisition_No is null. In this query, we have used both AND and OR operators to combine the clauses.
Sample Response
{
    "data": [
        {
            "Status": "Created",
            "PO_Date": "2022-05-10",
            "Discount": 9990,
            "PO_Number": "PO-JL-3876",
            "id": "4876876000001125176"
        },
        {
            "Status": "Created",
            "PO_Date": "2023-04-06",
            "Discount": 370.37,
            "PO_Number": "PO-DA-1932",
            "id": "4876876000003561019"
        }
    ],
    "info": {
        "count": 2,
        "more_records": false
    }
}

We hope you found this post useful and that it has given you a better understanding of COQL queries. In our next post, we will discuss the rest of the field types, aggregate functions with more examples, and provide more queries to help you get started.

If you have any questions or feedback, please let us know in the comments below, or write to us at support@zohocrm.com. We would love to hear from you! 

Additionally, if you have any questions about the COQL API or how to construct a query, kindly let us know in the comments.

Additional Reading:


    • Recent Topics

    • Can't create task programmatically using deluge

      I have a Date/Time field like this when it is edited, I want to create a task using deluge function. I use the code below to create a task. but unfortunately, the task is never created even I run it using 'execute' button on function editor. what went
    • Open word documents directly within zoho writer without converting

      There was an article in the help page that said that there would be a feature where zoho writer can directly open MS Word files without the need to convert those files to zoho format. It was said that it would be available by Q1 2023. Here is the article
    • Not receiving email at Outlook

      Hi, I've set up the account and can do everything except receiving email at Outlook. Please find print screen below parameters configured and advise what could went wrong. I can send email from both Webmail and Outlook. I could, however, receive email
    • Office 365 and Zoho CRM

      Does anyone have this synching properly. I configured it and the Zoho Calendar shows up in 365 but nothing comes from 365 into zoho crm. I have enabled the two way. No errors are being generated. If anyone has some insights I would really appreciate
    • To unblock , ensure atleast 5% free space of your total mailbox size exists after email deletion.

      Bom dia, Já deletei todos os e-mails , mas ainda não consigo desbloquear o e-mail comercial@hidrotecnicauberlandia.com.br. Já faz dias que deletei, mas ainda não desbloqueia quando sigo os passos de UNLOCKED ME. Por favor me ajudem.
    • Kiosk Page Refresh

      We have a Kiosk running from a button in contacts to update values and also add related lists, which works great, but when the kiosk is finished the page does not refresh to show the changes. Is there a way to force the contact to refresh/update when
    • Zoho does not send invitation email if meeting is created in calendar

      Problem: I create a meeting in calendar and add attendees. After "Save" button it asks me if I want to send email to all ettendees, I click Send. But none emails are sent. I did try that over outlook (connected thru active sync) or in zoho web mail. Nothing
    • Change Background in PDF Template

      Background PDF Hi, I want to ask a question. I want to create a background template with my own image. Above is an example that I made, why does the result not fit the A4 format? Like cut off. I used an A4 Portrait image, is there a size error? can you
    • Spotlight #7 - Automatic Transitions in Blueprint

      Previously, records could not be moved from one state to another without user intervention. With automatic transitions, move records from one state to another automatically, when it elapses its pre-defined time. This Spotlight discusses how automatic
    • Accepted meeting invites not showing on calendar

      I can receive a calendar invite to a meeting, I confirm I can attend and hit accept. I then check my calendar and it doesn't show. 30 seconds later, it does show up but it is delayed leaving the feeling something didn't work correctly. Can this be improved,
    • Cross module filtering is now supported in CRM

      Editions: All DCs: All Release plan: This enhancement is being released in phases. It is now available in AU, JP, and CN DCs. Help resource: Advanced filters The Cross-module filtering enhancement is now available to all CRM accounts in the following
    • Optimizing Zoho CRM & Xero Workflow – Advice Neede

      Hi everyone, We’ve been using Zoho for all CRM functions and Xero for all accounting, but the workflow between the two has become difficult to manage. The business does not want to move from Xero, as it's the accountants’ preferred system, but we need
    • No fue posible enviar el mensaje;Motivo:553 Relaying disallowed. Invalid Domain - admin@laboratoriosantarosa.org

      Hola Renovamos después del tiempo el dominio, y luego de eso se cayó el servicio de correo. Seguimos las indicaciones que se indican en este articulo, sin embargo, hasta el momento solo podemos recibir correos pero no enviar. Hemos actualizado los registros
    • Zoho Error: This Operation has been restricted. Please contact support-as@zohocorp.com for further details

      Hello There, l tried to verify my domain (florindagoreti.com.br) and its shows this error: This Operation has been restricted. Please contact support-as@zohocorp.com for further details. Screenshot Given Below -  please check what went wrong. Thanks
    • Error AS101 when adding new email alias

      Hi, I am trying to add apple@(mydomain).com The error AS101 is shown while I try to add the alias.
    • My IMAP mail suddenly stopped working

      On my iPhone and iPad, IMAP stopped working for my Zoho account with the error "User name or password incorrect" and "Invalid credentials failure" however I was able to access via web with the same credentials. Also stopped working on Apple Mail client.
    • When choosing custom view, load a particular Kanban view by defualt

      I have two custom views defined (say viewA, viewB) in the Leads module. I also have a Kanban views (say K1 and K2) defined in the Leads module. What I would like is that if I select viewA, it automatically loads Kanban via K1. If I select viewB, it automatically
    • Use result of one formula field for another formula field

      Can I pull data from one formula field as one of the values for another formula field? I tried doing it and it's returning an "invalid formula" error so I'm not sure if I made the formula incorrectly or if it's just really not possible to do that. Also,
    • Windows Desktop App - request to add minimization/startup options

      Support Team, Can you submit the following request to your development team? Here is what would be optimal in my opinion from UX perspective: 1) In the "Application Menu", add a menu item to Exit the app, as well as an alt-key shortcut for these menus
    • Export all Zoho desk tickets for past 3 months

      Hi I need to export ticket data from Zoho Desk. Specifically, I'm looking to: Export the last 3 months of tickets⁠ include ticket categories, timestamps, resolutions, agent responses (basically as much data as possible) the ticket content being the most
    • Zoho Calendar (Refresh Rate)

      Why don't the calendars refresh more than every 12 hours? That is crazy. I cannot be the only user who wants to see this change? I see and understand that I can MANUALLY update them, but need them to auto refresh either (1) whenever there is a change
    • Unattended Sessions - Groups and Access

      I would like to see Groups to organize Unattended Computers (what is currently labeled "My Computers") and a way to restrict access to individual users to specific groups.
    • No Hope for Zoho Meeting

      Zoho Meeting is just the poorest meeting app I've come across in a long time. The support sucks too. I called to see if there was anything that could be done on the backend and while I was on a test meeting with support the video was lagging and freezing
    • Add clients without needing a client company

      I, like many people, deal directly with individual clients rather than companies. It's really obnoxious to have to add a client company and treat my client, who is an individual person, as a company. Zoho - can you please build in a way to bypass the need for the client to be part of a company? This is a problem in cliq as well - I want to invite my clients to channels in Cliq but needing to create a company is confusing for them and makes them feel as if they don't belong on the app. But that's
    • Client reminders

      Hi Is there anyway to send automatic client reminders when we are pending a response from them? For instance, in a blueprint, say you have a transition that asks them for some additional information... They may take a while to reply, so is there a way
    • Add Image Upload Field to Zoho Bookings Registration Form

      Hi, We would like to request the addition of an image upload field to the Zoho Bookings registration form. Currently, Zoho Bookings only supports text-based fields (e.g., Single Line, Multi-Line, Email, Checkbox, Dropdown, Radio Button, and Date), but
    • Current Year Merge Tag

      I am looking for a way to add the current year dynamically to email campaigns. For example "Copyright 2024", so that templates are always up to date and this would also really help with automations. Another example could be a Happy New Year email which
    • Blueprints: Create Global Transitions

      Dear Zoho Team, it would be nice we could create global transitions for blueprints. The use case would be the following: We have 4 different processes with the same transitions in different orders. We could create 4 different blueprints, but whenever
    • Check-in and check-out time calculation discrepancy as shown in a screen recording

      Please see linked screen recording for my question: https://workdrive.zohoexternal.com/external/94dd0267dc877b3f827cc09b294625105627680700cec50e71d36c08e94cb257
    • Zoho marketing hub integration with WordPress WooCommerce

      Hello All,  I am a Zoho One User and we are using Zoho Marketing Hub we also have a website on Wordpress and we use Woo Commerce as our store.  im looking to find out if Zoho Marketing Hub Integrates with WooCommerce   ideally we would like to create Journeys or campaigns series based on customer behavior such as buying or already have purchased specific products. or if they go to the store but don't buy (abandon cart follow)  i saw that there is a wordpress plugin for Zoho Campaigns https://wordpress.org/plugins/zoho-campaigns/ but
    • Need help in search with formula culums in reports

      Hello, I do not know where to start with this one : I have a customer report with all that was bought and paid by my customers. It can be many records for one specific customer. Ex. Customer A has 1 record for a purchase of 1000 $, and 2 records of payments
    • how to send recurring estimates instead of recurring invoices

      Hello, Is it possible to use the recurring invoice functionality to send recurring estimate to our customers ? We first need to send them an invoice in order to receive their purchase order and then send them the invoice with their purchase order number
    • AS101

      I'm having issue while adding email alies to an email. Please help.
    • Tracking UTM Campaign information in CRM

      Hi All, We have had this questions asked a few times lately so thought it would be a great idea to post it here for others benefit.  Many have asked this: How can I track campaign information in CRM from my online campaigns and report on UTM tracking details?  Below is what we have set up for other businesses who are using UTM Codes for all their campaigns. Follow the 4 steps below to set this up for your CRM: 1. Create Fields in CRM Leads Module Add a field  in the Leads module called 'Referrer
    • Adding fields to campaign members

      Is it possible to add fields to campaign members? I want to be able to insert a date that certain actions happened as we progress a client, but can't see where or how I might be able to do that
    • Amazon Integration

      Hi, I am seller on Amazon , & I would like to sign up for Zoho books. However my question is can we automate/integrate invoicing, charges and returns in amazon with Zoho using API? Do you have a developer for this? I did take a look at zapier however it just has a create Invoice function nothing else.
    • Remove Zoho contract upsell at customer sign completion page

      Hello, I am going through testing for a zoho contract for my organization and I noticed that after the customer signs the contract they are forwarded to a completion page that tries to sell them on using zoho contracts. I find that very unprofessional
    • Retain Jira Ticket When Merging Tickets in Zoho Desk

      Hi, We would like to request a feature enhancement for Zoho Desk's ticket merging process regarding Jira ticket retention. Current Behavior: When merging two tickets (manually via the interface or through the API), we can select the "master" ticket into
    • Workdrive comment links stopped working.

      I have marked a PDF file with 95 comments, they have worked for a while. When i clicked on them they brought me to the correct page and showed me the outline that i had drew on the plans. The comments included the page number of the outline, but now it
    • Generate a Zoho Sign link

      From time to time I get a response "I never received your you e-document for electronic signature" is there a way to generate a Zoho Sign link to share.
    • Next Page