A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.
The Zoho CRM API is how an app or AI agent works with a Zoho CRM org: reading and writing records in a module like Leads or Deals, searching and querying across modules, adding notes and tasks, and reading the modules, fields, and users that describe the account. Access is granted through an OAuth access token, and the token carries granular scopes that decide which modules and operations a call can read or write. A record change can be pushed to a callback URL, so an integration learns about activity without polling.
How an app or AI agent connects to Zoho CRM determines what it can reach. There is a route for making calls, a route for receiving events when records change, and a hosted server that exposes Zoho CRM tools to agents, and each is governed by the access token behind it and the scopes that token carries.
The REST API takes JSON request bodies, returns JSON, and is reached at a data-center host like https://www.zohoapis.com/crm/v8, with the version pinned in the path. A call authenticates by sending an OAuth access token in the Authorization header as 'Zoho-oauthtoken
Zoho CRM POSTs a notification to a callback URL when a record is created, edited, or deleted in a subscribed module. An integration enables a channel through the actions/watch endpoint, naming the events and the URL, and Zoho delivers the change so the integration does not have to poll.
Zoho publishes a first-party Model Context Protocol server that exposes Zoho CRM tools to AI agents. It is split into four servers: Data Insights (read-only queries, including COQL, and field schemas), Data Operations (create, read, update, delete, and bulk operations across modules), Module Customization (modules, fields, and layouts), and Workflow and Process Automation (workflow rules and task actions). A tool's first use opens an OAuth login, and every action runs under the signed-in user's CRM permissions.
A user grants a client access through Zoho's authorization endpoint, naming the exact scopes requested, and the client exchanges the returned code for an access token and a refresh token. The access token is sent in the Authorization header as 'Zoho-oauthtoken
An access token is valid for one hour. A refresh token, which has an unlimited lifetime until the user revokes it, is used to obtain new access tokens without sending the user through the consent screen again.
For server-to-server integrations with no end user to log in, a self client generates an authorization code, and then tokens, directly from the API console for the org that owns the client. The same scopes and token model apply.
The Zoho CRM API is organized by what an agent acts on, like the records inside a module (Leads, Contacts, Accounts, Deals), the queries that read across modules, the metadata that describes modules and fields, and the notes, tasks, and users attached to a CRM org. Each area has its own methods, and a write in the records area changes live customer data.
Methods for reading and writing records inside a module, like Leads, Contacts, Accounts, and Deals.
Methods for reading records with SQL-like queries across a module and its related modules.
Methods for reading the structure of the org: which modules exist and the fields inside them.
Methods for the notes attached to records and the tasks that drive follow-up.
Methods for reading the people and their roles in the CRM org.
Asynchronous jobs for exporting or importing large sets of records as files.
Methods for subscribing a callback URL to record create, edit, and delete events.
Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.
| Method | Endpoint | What it does | Access | Permission | Version | |
|---|---|---|---|---|---|---|
RecordsMethods for reading and writing records inside a module, like Leads, Contacts, Accounts, and Deals.9 | ||||||
| GET | /crm/v8/{module_api_name} | Get a list of records from a module, like Leads or Deals, with field selection, sorting, and pagination. | read | modules.{module}.READ | Current | |
Long scope: ZohoCRM.modules.{module}.READ, or ZohoCRM.modules.ALL. The fields parameter is mandatory and takes up to 50 field names. Acts onrecord Permission (capability) modules.{module}.READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /crm/v8/{module_api_name}/{record_id} | Get a single record from a module by its ID. | read | modules.{module}.READ | Current | |
Long scope: ZohoCRM.modules.{module}.READ, or ZohoCRM.modules.ALL. Acts onrecord Permission (capability) modules.{module}.READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /crm/v8/{module_api_name} | Insert one or more records into a module. | write | modules.{module}.CREATE | Current | |
Long scope: ZohoCRM.modules.{module}.CREATE, ALL, or ZohoCRM.modules.ALL. Up to 100 records per call. Acts onrecord Permission (capability) modules.{module}.CREATEVersionAvailable since the API’s base version Webhook event module.createRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /crm/v8/{module_api_name} | Update one or more existing records in a module. | write | modules.{module}.UPDATE | Current | |
Long scope: ZohoCRM.modules.{module}.UPDATE, ALL, or ZohoCRM.modules.ALL. Up to 100 records per call. Acts onrecord Permission (capability) modules.{module}.UPDATEVersionAvailable since the API’s base version Webhook event module.editRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /crm/v8/{module_api_name}/upsert | Insert records or update them if a matching record already exists, based on duplicate-check fields. | write | modules.{module}.ALL | Current | |
Long scope: ZohoCRM.modules.{module}.ALL, or ZohoCRM.modules.ALL. Acts onrecord Permission (capability) modules.{module}.ALLVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /crm/v8/{module_api_name} | Delete one or more records from a module by ID. | write | modules.{module}.DELETE | Current | |
Long scope: ZohoCRM.modules.{module}.DELETE, ALL, or ZohoCRM.modules.ALL. Deleted records move to the Recycle Bin. Acts onrecord Permission (capability) modules.{module}.DELETEVersionAvailable since the API’s base version Webhook event module.deleteRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /crm/v8/{module_api_name}/search | Search a module's records by criteria, email, phone, or a word, returning matches in that module. | read | modules.{module}.READ | Current | |
Also needs ZohoSearch.securesearch.READ. Up to 10 criteria and 2,000 records per search. Acts onrecord Permission (capability) modules.{module}.READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /crm/v8/{module_api_name}/deleted | Get the list of records that were deleted from a module and moved to the Recycle Bin. | read | modules.{module}.READ | Current | |
Long scope: ZohoCRM.modules.{module}.READ, or ZohoCRM.modules.ALL. Acts onrecord Permission (capability) modules.{module}.READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /crm/v8/{module_api_name}/actions/mass_update | Update a single field to the same value across many records in a module in one call. | write | modules.{module}.UPDATE | Current | |
Long scope: ZohoCRM.modules.{module}.UPDATE, ALL, or ZohoCRM.modules.ALL. Acts onrecord Permission (capability) modules.{module}.UPDATEVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Query (COQL)Methods for reading records with SQL-like queries across a module and its related modules.1 | ||||||
| POST | /crm/v8/coql | Get records using a COQL (CRM Object Query Language) SELECT query, with filtering, joins, and aggregation. | read | coql.READ | Current | |
Long scope: ZohoCRM.coql.READ, plus ZohoCRM.modules.{module}.READ for each module queried. Up to 200 rows per call, 100,000 via pagination. Acts onquery Permission (capability) coql.READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Modules & Fields metadataMethods for reading the structure of the org: which modules exist and the fields inside them.3 | ||||||
| GET | /crm/v8/settings/modules | Get the list of all modules in the org, both standard and custom. | read | settings.modules.READ | Current | |
Long scope: ZohoCRM.settings.modules.READ, or ZohoCRM.settings.ALL. Acts onmodule Permission (capability) settings.modules.READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /crm/v8/settings/fields | Get the field metadata for a module, including each field's API name, data type, and layout. | read | settings.fields.READ | Current | |
Long scope: ZohoCRM.settings.fields.READ, or ZohoCRM.settings.ALL. The module parameter is required. Acts onfield Permission (capability) settings.fields.READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /crm/v8/settings/fields/{field_id} | Get the metadata of a single field in a module by its unique ID. | read | settings.fields.READ | Current | |
Long scope: ZohoCRM.settings.fields.READ, or ZohoCRM.settings.ALL. The module parameter is required. Acts onfield Permission (capability) settings.fields.READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Notes & TasksMethods for the notes attached to records and the tasks that drive follow-up.4 | ||||||
| GET | /crm/v8/Notes | Get the list of notes across the org, or the notes attached to a specific record. | read | modules.notes.READ | Current | |
Long scope: ZohoCRM.modules.notes.READ, or ZohoCRM.modules.ALL. Record-scoped notes use /{module}/{record_id}/Notes. Acts onnote Permission (capability) modules.notes.READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /crm/v8/Notes | Create one or more notes, attaching each to a parent record. | write | modules.notes.CREATE | Current | |
Long scope: ZohoCRM.modules.notes.CREATE, ALL, or ZohoCRM.modules.ALL. Acts onnote Permission (capability) modules.notes.CREATEVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /crm/v8/Tasks | Get the list of Tasks records, the follow-up activities tracked in the CRM. | read | modules.tasks.READ | Current | |
Tasks is a standard module read through the Records API. Long scope: ZohoCRM.modules.tasks.READ, or ZohoCRM.modules.ALL. Acts ontask Permission (capability) modules.tasks.READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /crm/v8/Tasks | Create one or more Tasks records to schedule follow-up against a contact, lead, or deal. | write | modules.tasks.CREATE | Current | |
Tasks is a standard module written through the Records API. Long scope: ZohoCRM.modules.tasks.CREATE, ALL, or ZohoCRM.modules.ALL. Acts ontask Permission (capability) modules.tasks.CREATEVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
UsersMethods for reading the people and their roles in the CRM org.2 | ||||||
| GET | /crm/v8/users | Get the list of users in the CRM org, filtered by a type like ActiveUsers or AdminUsers. | read | users.READ | Current | |
Long scope: ZohoCRM.users.READ, or ZohoCRM.users.ALL. Acts onuser Permission (capability) users.READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /crm/v8/users/{user_id} | Get the details of a single user by their ID. | read | users.READ | Current | |
Long scope: ZohoCRM.users.READ, or ZohoCRM.users.ALL. Acts onuser Permission (capability) users.READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Bulk read & writeAsynchronous jobs for exporting or importing large sets of records as files.2 | ||||||
| POST | /crm/bulk/v8/read | Start an asynchronous bulk read job to export a large set of records from a module to a file. | read | bulk.READ | Current | |
Long scope: ZohoCRM.bulk.READ (or ALL), plus ZohoCRM.modules.{module}.READ. Returns a job ID; the result is a downloadable ZIP. Acts onbulk_read_job Permission (capability) bulk.READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /crm/bulk/v8/write | Start an asynchronous bulk write job to insert, update, or upsert records from an uploaded CSV. | write | bulk.CREATE | Current | |
Long scope: ZohoCRM.bulk.CREATE, or ZohoCRM.bulk.ALL plus the module write scope. Up to 25,000 records per job, from a zipped CSV. Acts onbulk_write_job Permission (capability) bulk.CREATEVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
NotificationsMethods for subscribing a callback URL to record create, edit, and delete events.3 | ||||||
| POST | /crm/v8/actions/watch | Subscribe a callback URL to record create, edit, or delete events on a module. | write | notifications.CREATE | Current | |
Long scope: ZohoCRM.notifications.CREATE, or ZohoCRM.notifications.ALL. Events take the form {module}.create, {module}.edit, {module}.delete, or {module}.all. Acts onnotification Permission (capability) notifications.CREATEVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /crm/v8/actions/watch | Get the details of the notifications a user has enabled. | read | notifications.READ | Current | |
Long scope: ZohoCRM.notifications.READ, or ZohoCRM.notifications.ALL. Acts onnotification Permission (capability) notifications.READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /crm/v8/actions/watch | Stop the instant notifications a user enabled for a channel. | write | notifications.DELETE | Current | |
Long scope: ZohoCRM.notifications.DELETE, or ZohoCRM.notifications.ALL. Acts onnotification Permission (capability) notifications.DELETEVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Zoho CRM can notify an app when a record is created, edited, or deleted in a module. An integration subscribes a callback URL to the events it cares about, so it learns about activity without polling.
| Event | What it signals | Triggered by |
|---|---|---|
{module}.create | A record was created in a subscribed module, like a new Lead or Deal. Delivered to the channel's callback URL. | /crm/v8/{module_api_name} |
{module}.edit | A record was updated in a subscribed module. Delivered to the channel's callback URL. | /crm/v8/{module_api_name} |
{module}.delete | A record was deleted in a subscribed module. Delivered to the channel's callback URL. | /crm/v8/{module_api_name} |
Zoho CRM meters API use by a daily credit balance and by how many calls run at once, rather than by a fixed per-minute rate. The credit allowance and the concurrency ceiling both scale with the org's edition and user count.
Zoho CRM meters API use by credits and by concurrency, not by a per-minute rate. Each org gets a daily credit balance that resets on a 24-hour rolling window and scales with edition and user count: Standard starts at 50,000 plus 250 per user (capped at 100,000), Professional at 50,000 plus 500 per user, and Enterprise or Zoho One at 50,000 plus 1,000 per user. A typical call costs one credit, while a heavier call costs more, like five credits to convert a lead. Concurrency caps how many calls run at once, at 10 for Standard, 15 for Professional, and 20 for Enterprise, with a separate sub-concurrency limit of 10 across all editions for resource-intensive calls like search, query, and large inserts. Going over returns HTTP 429.
A list call pages with page and per_page, where per_page returns at most 200 records. Reading past 2,000 records switches to cursor pagination: a response carries a next_page_token, which is passed back as page_token (alongside page) to fetch up to 100,000 records in total. A page_token is user-specific and expires after 24 hours. COQL paginates the same way through its LIMIT and OFFSET clauses.
A records read or write call handles up to 100 records at a time. A COQL query returns up to 200 rows per call. A bulk write job imports up to 25,000 records from a zipped CSV, and bulk read exports large sets to a downloadable ZIP, both without drawing on the standard credit balance.
The status codes an agent should handle, and what to do about each.
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 400 | INVALID_DATA / BAD REQUEST | The request or an ID in it is invalid, for example a malformed body, a wrong data type, or a missing mandatory field. | Read the error code and details in the response, correct the data or parameters, and resend. The request is not retryable as-is. |
| 401 | AUTHORIZATION ERROR | Authentication failed, for example a missing, invalid, or expired access token. | Send a valid access token in the Authorization header, refreshing it with the refresh token if it has expired. |
| 403 | OAUTH_SCOPE_MISMATCH / NO_PERMISSION | The token lacks the scope the call needs, or the user lacks permission for the operation in the CRM. | Re-authorize with the scope the method requires, or grant the user the needed CRM permission, then retry. |
| 404 | NOT FOUND | The requested record, module, or URL pattern does not exist or is not visible to this token. | Check the module API name, record ID, and path, and confirm the record exists in this org. |
| 405 | METHOD NOT ALLOWED | The HTTP method used is not allowed for this endpoint. | Use the method the endpoint supports, for example GET to read and PUT to update records. |
| 429 | TOO MANY REQUESTS | The daily credit balance was exhausted, or too many calls ran at once and hit the concurrency or sub-concurrency limit. | Back off and retry, smooth out concurrent calls, and move large jobs to the bulk APIs, which do not draw on the standard credit balance. |
| 500 | INTERNAL SERVER ERROR | An unexpected error on Zoho's side. | Retry with backoff, and contact Zoho support if it persists. |
Zoho CRM pins the API version in the request path, and ships new versions as numbered releases without deprecating the older ones at the same time.
v8 is the current version, pinned in the path as /crm/v8. It added APIs for data sharing rules across users and modules, a related-record count, workflow and connected-workflow control, calendar and cadences, and richer field types, and introduced an OpenAPI 3.0.0 specification for the API. Zoho did not deprecate the older versions when v8 shipped.
The version preceding v8, pinned as /crm/v7. It remains available, as Zoho keeps older versions working when a new one ships.
Pin v8 in the path and move up on a schedule that suits the integration.
Zoho CRM API v8 release notes ↗Bollard AI sits between a team's AI agents and Zoho CRM. Grant each agent exactly the access it needs, read or write, module by module, and every call is checked and logged.