Zoho CRM COQL: Query Data Across Modules
How COQL queries work, what they cost in API credits and how to paginate past 100,000 records with an ID-based cursor.

Learn how Zoho CRM COQL queries fetch fields across lookups, how LIMIT drives credit costs and how to paginate past 100,000 records with an ID cursor.
Sales leaders ask questions that cross modules: which open deals over a certain value belong to accounts in a given industry, or how many contacts each region added last quarter. Pulling whole modules through the API and joining them in a spreadsheet is slow and expensive in API credits. Zoho CRM COQL, the CRM Object Query Language behind the Query API, lets you ask these questions in a SQL-like form and get back only the records and fields you need. This guide explains how COQL works, where it fits next to Get Records, Search and Bulk Read, how its limits and credits behave, and how to paginate beyond the first 100,000 records, with a worked example.
What COQL is
COQL is a read-only query language for Zoho CRM data. You write a SELECT statement using module and field API names rather than labels, and send it as JSON to the Query API endpoint. A typical request body looks like this:
{
"select_query": "select Deal_Name, Amount, Stage, Account_Name.Industry from Deals where (Stage != 'Closed Lost' and Amount > 50000) order by Amount desc limit 0, 200"
}
According to Zoho's COQL overview, the Search API works within one module, while the Query API can retrieve fields from modules linked through lookup fields. In the example above, Account_Name is the lookup from the deal to its account, and Account_Name.Industry reads the account's industry in the same query.
The building blocks of a COQL query
ClauseWhat it doesPoints to rememberSELECTLists the fields to returnUse API names; up to 500 fields; aliases with ASFROMThe base moduleSubforms and multi-select lookup linking modules can be queried tooWHEREFilter criteriaUp to 25 criteria, grouped with bracketsGROUP BYGroups rowsWorks with aggregate functionsORDER BYSortingDefaults to record ID ascending if omittedLIMIT offset, limitPagingDefault 200 records, maximum 2,000 per call
COQL also supports the aggregate functions SUM, AVG, COUNT, MIN and MAX, which lets you calculate totals and averages inside the CRM rather than exporting data first. Aliases are useful when lookup paths make the response keys long; for example, Account_Name.Parent_Account.Account_Name can be returned as "Parent Account Name".
Each field type supports its own set of comparators, so a date field and a picklist field accept different operators. Zoho's documentation lists them by field type, and it is worth checking before writing filters on unusual fields such as multi-select picklists.
How Zoho CRM COQL limits and credits work
COQL is efficient, but it is not free. The credit cost of each call depends on the LIMIT value:
- LIMIT between 1 and 200 costs 1 API credit
- LIMIT between 201 and 1,000 costs 2 credits
- LIMIT between 1,001 and 2,000 costs 3 credits
That makes larger pages cheaper per record. Fetching 2,000 records in one call costs 3 credits, while fetching them in pages of 200 costs 10. For bulk reads that consume a lot of credits, the trade-off is worth planning, especially if other integrations share the same daily allowance.
There is also a ceiling on offset pagination. With the same criteria, you can page through up to 100,000 records. Beyond that, Zoho recommends adding a criterion such as id greater than the last record ID you received and starting again, or switching to the Bulk Read API for very large extracts.
COQL, Get Records, Search or Bulk Read?
NeedBest fitWhyA page of recent records from one moduleGet RecordsSimple, supports sorting and modified-since headersFind records matching a valueSearchBuilt for lookups by email, phone or criteriaFilter on several fields or across lookupsCOQLJoins through lookups and flexible WHERE clausesCounts, sums and averagesCOQL aggregatesCalculations happen in the CRMHundreds of thousands of recordsBulk ReadAsynchronous export designed for volume
A useful rule: if you find yourself fetching records and then filtering most of them out in code, COQL can probably do the filtering for you and save credits.
Worked example: open pipeline by industry, paginated safely
Suppose a sales director wants a weekly extract of all open deals over 50,000, with the account's industry, loaded into a reporting database. The org has around 180,000 deals, of which roughly 40,000 match. The script below runs the query in pages of 2,000, uses the record ID as a stable cursor rather than relying only on offsets, and stops when a page comes back short. It is illustrative and untested; adapt field names and error handling to your org.
import requests
API = "https://www.zohoapis.com" # use the api_domain returned with your token
def coql(token, query):
resp = requests.post(
f"{API}/crm/v8/coql",
headers={"Authorization": f"Zoho-oauthtoken {token}"},
json={"select_query": query},
timeout=30,
)
if resp.status_code == 204:
return []
resp.raise_for_status()
return resp.json().get("data", [])
def open_deals_by_industry(token):
last_id = "0"
while True:
query = (
"select id, Deal_Name, Amount, Stage, Account_Name.Industry "
"from Deals "
f"where (Stage not in ('Closed Won', 'Closed Lost') and Amount > 50000 and id > {last_id}) "
"order by id asc limit 0, 2000"
)
rows = coql(token, query)
for row in rows:
yield row
if len(rows) < 2000:
break
last_id = rows[-1]["id"]
Because each page restarts from the last ID with offset zero, the 100,000-record offset ceiling never applies, and records added during the run do not shift the pages. At 2,000 records per call, the 40,000 matching deals take about 20 calls and roughly 60 credits, compared with about 200 credits for pages of 200.
For the weekly summary itself, an aggregate query can do the counting:
QueryResultselect Account_Name.Industry, COUNT(id), SUM(Amount) from Deals where Stage not in ('Closed Won', 'Closed Lost') group by Account_Name.IndustryOne row per industry with deal count and total value
Check the exact comparators supported for each field type, such as "not in" on picklists, against Zoho's field-type documentation before relying on them.
Common COQL mistakes
- Using field labels instead of API names. Find API names under Setup, Developer Hub, APIs and SDKs, API Names.
- Forgetting quotes around values with spaces, special characters or reserved words.
- Relying on deep offset pagination for large sets instead of an ID-based cursor.
- Selecting every field "just in case", which increases response sizes and processing time.
- Running ad-hoc queries in production integrations without logging, so nobody knows where credits went.
- Treating COQL as a write tool. It reads data; inserts and updates still go through the record APIs.
Making queries maintainable
Store each production query in one place with a short description of its purpose, the fields it depends on and who asked for it. When administrators rename or remove fields, a quick search of stored queries shows which integrations will break. Log the number of records returned and the credits used per run, so changes in volume or cost are visible. Review queries when the CRM layout changes, and remove those nobody uses.
It also helps to test queries against a sandbox before production, particularly when they join through several lookups. A query that works on a small dataset can still return unexpected results when lookups are empty, so check how null values appear in the response and handle them in the code that consumes it.
COQL usually reduces credit use, but it still draws from the same pool; our guide to Zoho CRM API limits explains how to budget for it. When queries feed nightly jobs, our guide to the Zoho CRM schedule function shows how to run them reliably inside the CRM.
Frequently Asked Questions
What is COQL in Zoho CRM?
COQL is the CRM Object Query Language used by Zoho CRM's Query API. It lets you fetch records with SQL-like SELECT statements, including fields from modules linked by lookups.
How many records can a COQL query return?
Up to 2,000 per call, with a default of 200. With the same criteria you can paginate through up to 100,000 records; beyond that, add an ID-based criterion or use Bulk Read.
How many API credits does COQL use?
It depends on LIMIT: 1 credit for up to 200 records, 2 for 201 to 1,000 and 3 for 1,001 to 2,000.
Can COQL update or delete records?
No. COQL only reads data. Use the insert, update, upsert or delete record APIs for changes.
Query your CRM data with us
We design COQL queries, reporting extracts and integrations that get the right data out of Zoho CRM without wasting credits. See our CRM and API integration services, or talk to us about your reporting needs.
About the Author
Manav Sharma is the founder of Insyrge and a CRM solutions architect. He works across Zoho, Salesforce, HubSpot, Odoo and more, designing the CRM setups, integrations and automations that keep sales and operations teams working from the same data.
Need Help Implementing This in Your Business?
Our certified Zoho consultants and automation experts can help you design and deploy custom workflows tailored to your operations.
Book Free Consultation