Zoho CRM
The Zoho CRM integration lets Helios agents call the Zoho CRM REST API through your own OAuth app, and run agents automatically when records in Zoho CRM's built-in modules are created, updated, or deleted.
What your agents can do
Helios agents call the Zoho CRM REST API with the connected user's permissions and granted OAuth scopes. Agents can work with records, COQL queries, notes, attachments, files, emails, bulk jobs, tags, users, and settings.
- Create leads from an email or a form, and convert them to contacts, accounts, and deals
- Find records with search or COQL, and update their fields
- Move deals between stages, and add notes, tasks, and attachments to records that support them
- Send email and mail merge documents from a record, and read the emails linked to it
- Export or import many records at once with the bulk read and bulk write APIs
- With Admin access, change fields, layouts, and workflow rules, and manage users
Agents can send GraphQL queries to /crm/graphql when the connected Zoho account supports them. Helios requests scopes to enable the profile's GraphQL schema and read data. See Zoho's GraphQL guide.
Agents can only call these Zoho hosts:
- Your data center's API domain, such as
https://www.zohoapis.eu. upload.zoho.comfor bulk write files, and the fasterupload-accl.zoho.com,upload-accl.zoho.eu, orupload-accl.zoho.inin the US, EU, and IN data centers.- In the US data center,
download.zoho.comanddownload-accl.zoho.comfor audit log exports and backups. Zoho doesn't document these download hosts for other data centers, so agents there can't download those files.
Every call uses your organization's Zoho API credits. See Limits.
Authentication
| Method | Type | Description |
|---|---|---|
| Your own Zoho CRM OAuth app | OAuth 2.0 | A server-based client you register in the Zoho API Console |
See Integration authentication for how credentials are stored and injected.
Your own Zoho CRM OAuth app
You need a Zoho account to register the client in the Zoho API Console. Zoho records every change as the user who approves access, with that user's permissions. For Admin access, that user needs the Administrator profile in Zoho CRM.
-
Open the Zoho API Console for your data center, such as api-console.zoho.com or api-console.zoho.eu. Click GET STARTED, or add a new client if you already have one.
-
Choose Server-based Applications and click CREATE NOW. Enter a client name and a homepage URL, and add this redirect URI:
https://api.heliosapp.com/integrations/zoho_crm/oauth_callbackClick CREATE.
-
Copy the Client ID and Client Secret from the client's Client Secret tab.
-
In Helios, choose Your own Zoho CRM OAuth app. Enter Client ID and Client Secret.
-
Check Admin access if a Zoho CRM administrator will approve access and agents need to change settings, manage users, or back up data.
-
If your Zoho account isn't in the US data center, set Base URL to your data center's API domain from the table below. Helios sends you to that data center to approve access. US accounts can leave it empty.
-
Save, then approve access in Zoho. If you belong to more than one Zoho CRM organization, pick the one Helios should use.
| Data center | Accounts server | Base URL |
|---|---|---|
| United States | https://accounts.zoho.com | https://www.zohoapis.com (default) |
| Europe | https://accounts.zoho.eu | https://www.zohoapis.eu |
| India | https://accounts.zoho.in | https://www.zohoapis.in |
| Australia | https://accounts.zoho.com.au | https://www.zohoapis.com.au |
| Japan | https://accounts.zoho.jp | https://www.zohoapis.jp |
| Canada | https://accounts.zohocloud.ca | https://www.zohoapis.ca |
| Saudi Arabia | https://accounts.zoho.sa | https://www.zohoapis.sa |
| United Kingdom | https://accounts.zoho.uk | https://www.zohoapis.uk |
| UAE | https://accounts.zoho.ae | https://www.zohoapis.ae |
| Singapore | https://accounts.zoho.sg | https://www.zohoapis.sg |
| China | https://accounts.zoho.com.cn | https://www.zohoapis.com.cn |
Zoho lists its accounts servers at accounts.zoho.com/oauth/serverinfo. A sandbox or Developer Edition organization uses sandbox.zohoapis or developer.zohoapis instead of www.zohoapis, such as https://developer.zohoapis.com. Zoho tokens only work for the organization and environment they were issued for, so connect each one separately.
Helios also stores the data center that Zoho reports when you connect. A Base URL you set takes precedence over it.
A client in another data center
If you registered the client in one data center's console and your Zoho account is in another, enable your data center on the client:
- In the Zoho API Console, open the client and go to the Settings tab.
- Turn on the toggle next to your data center.
- Select Use the same OAuth credentials for all data centers and click OK.
Helios stores one client secret for the connection. By default, Zoho gives each data center its own client secret, and the token request fails with invalid_client when the secret doesn't match. See Zoho's multi data center guide.
Scopes and tokens
Helios asks for these scopes:
| Scope | What it's for |
|---|---|
ZohoCRM.modules.ALL | Read and change records, notes, attachments, and emails in every module |
ZohoCRM.modules.entity_scores.READ | Read the scores that scoring rules give records |
ZohoCRM.settings.READ | Read settings, such as modules, fields, layouts, and workflow rules |
ZohoCRM.settings.wizards.READ, ZohoCRM.settings.assignment_rules.READ, ZohoCRM.settings.fiscal_year.READ, ZohoCRM.settings.currencies.READ | Read wizards, assignment rules, the fiscal year, and currencies, which ZohoCRM.settings.READ doesn't cover |
ZohoCRM.settings.audit_logs.READ, ZohoCRM.settings.audit_logs.CREATE | Export the audit log. Zoho shows users who aren't administrators only their own and their subordinates' entries |
ZohoCRM.settings.recycle_bin.READ, ZohoCRM.settings.recycle_bin.UPDATE | Read the recycle bin and restore records from it |
ZohoCRM.users.READ, ZohoCRM.org.READ | Read users and the organization, and test the connection |
ZohoCRM.bulk.READ, ZohoCRM.bulk.CREATE | Run bulk read and bulk write jobs |
ZohoCRM.notifications.ALL | Create, renew, and remove the notification channel for triggers |
ZohoCRM.coql.READ | Run COQL queries |
ZohoCRM.graphql.READ, ZohoCRM.GraphQL.UPDATE | Enable the GraphQL schema and run GraphQL queries, on the editions that offer them |
ZohoCRM.files.CREATE, ZohoCRM.files.READ | Upload and download files |
ZohoCRM.mass_update.READ, ZohoCRM.mass_update.UPDATE | Update many records at once |
ZohoCRM.mass_delete.READ, ZohoCRM.mass_delete.DELETE | Delete many records at once |
ZohoCRM.mass_convert.leads.READ, ZohoCRM.mass_convert.leads.CREATE, and the same for quotes and salesorders | Convert many leads, quotes, or sales orders at once |
ZohoCRM.change_owner.READ, ZohoCRM.change_owner.CREATE | Change the owner of records |
ZohoCRM.send_mail.all.CREATE | Send email from records |
ZohoCRM.templates.email.READ, ZohoCRM.templates.inventory.READ | Read email and inventory templates |
ZohoCRM.share.ALL | Share records with other users |
ZohoCRM.features.READ, ZohoCRM.apis.READ | Read the organization's features and the available APIs |
ZohoCRM.composite_requests.CUSTOM | Send up to five API calls in one request |
ZohoCRM.Zia.enrichment.ALL | Enrich records with Zia |
ZohoCRM.settings.mailmerge.CREATE, ZohoCRM.settings.emails.ALL | Send, sign, and download mail merge documents |
ZohoSearch.securesearch.READ | Use the search API |
ZohoFiles.files.ALL | Upload bulk write files, and download audit log exports and backups |
ZohoWriter.documentEditor.ALL, ZohoWriter.merge.ALL | Merge records into Zoho Writer templates for mail merge |
ZohoSign.documents.ALL | Send mail merge documents for signature with Zoho Sign |
With Admin access checked, Helios also asks for these:
| Scope | What it's for |
|---|---|
ZohoCRM.settings.ALL | Change settings, such as fields, layouts, workflow rules, profiles, and territories |
ZohoCRM.settings.fiscal_year.UPDATE, ZohoCRM.settings.currencies.CREATE, ZohoCRM.settings.currencies.UPDATE | Change the fiscal year and currencies, which ZohoCRM.settings.ALL doesn't cover |
ZohoCRM.settings.recycle_bin.DELETE | Empty the recycle bin |
ZohoCRM.users.ALL | Add, change, and remove users |
ZohoCRM.org.ALL | Change the organization's details and photo |
ZohoCRM.bulk.backup.ALL | Schedule and read data backups |
Zoho checks each call against the profile of the user who approved access. A call that the profile doesn't allow, such as a mass update without the Mass Update permission, fails with NO_PERMISSION. The other calls still work.
Access tokens last one hour, and Helios renews them with the refresh token. Zoho refresh tokens don't expire until they're revoked. Zoho keeps at most 20 refresh tokens for each user, and creating the 21st invalidates the oldest. Each time you approve access, Zoho issues a new one. A user who connects many times can end an older connection's access. Connect that connection again. See Zoho's token validity.
If you change the client secret in the Zoho API Console, enter the new one in Client Secret through Manage and connect again. Connect again after you change Admin access too, so Zoho issues a token with the new scopes.
Triggers
Zoho CRM can start a Workflow when a record in one of its built-in modules is created, updated, or deleted. Helios creates a Zoho notification channel when you connect, so there is nothing to set up in Zoho. This needs the ZohoCRM.notifications.ALL and ZohoCRM.settings.READ scopes above. Zoho ends a channel after at most a week, so Helios replaces it every five days. When you delete the connection, Helios attempts to remove the channel. If removal fails, the channel stays active in Zoho until it expires.
The channel covers every module in the table below that your organization has. When a module is missing, or Zoho refuses to watch it, its events show as unavailable in the trigger picker with the reason.
If renewing the channel fails, for example because access was revoked, events stop. Save the connection again, or connect again, and Helios creates a new channel.
| Event | Description | Filters |
|---|---|---|
lead.created | A lead was created | None |
lead.updated | A lead was updated | changed field (pattern) |
lead.deleted | A lead was deleted | None |
account.created | An account was created | None |
account.updated | An account was updated | changed field (pattern) |
account.deleted | An account was deleted | None |
contact.created | A contact was created | None |
contact.updated | A contact was updated | changed field (pattern) |
contact.deleted | A contact was deleted | None |
deal.created | A deal was created | None |
deal.updated | A deal was updated | changed field (pattern), moved to stage (pattern) |
deal.deleted | A deal was deleted | None |
campaign.created | A campaign was created | None |
campaign.updated | A campaign was updated | changed field (pattern) |
campaign.deleted | A campaign was deleted | None |
task.created | A task was created | None |
task.updated | A task was updated | changed field (pattern) |
task.deleted | A task was deleted | None |
case.created | A case was created | None |
case.updated | A case was updated | changed field (pattern) |
case.deleted | A case was deleted | None |
meeting.created | A meeting was created | None |
meeting.updated | A meeting was updated | changed field (pattern) |
meeting.deleted | A meeting was deleted | None |
call.created | A call was created | None |
call.updated | A call was updated | changed field (pattern) |
call.deleted | A call was deleted | None |
solution.created | A solution was created | None |
solution.updated | A solution was updated | changed field (pattern) |
solution.deleted | A solution was deleted | None |
product.created | A product was created | None |
product.updated | A product was updated | changed field (pattern) |
product.deleted | A product was deleted | None |
vendor.created | A vendor was created | None |
vendor.updated | A vendor was updated | changed field (pattern) |
vendor.deleted | A vendor was deleted | None |
price_book.created | A price book was created | None |
price_book.updated | A price book was updated | changed field (pattern) |
price_book.deleted | A price book was deleted | None |
quote.created | A quote was created | None |
quote.updated | A quote was updated | changed field (pattern) |
quote.deleted | A quote was deleted | None |
sales_order.created | A sales order was created | None |
sales_order.updated | A sales order was updated | changed field (pattern) |
sales_order.deleted | A sales order was deleted | None |
purchase_order.created | A purchase order was created | None |
purchase_order.updated | A purchase order was updated | changed field (pattern) |
purchase_order.deleted | A purchase order was deleted | None |
invoice.created | An invoice was created | None |
invoice.updated | An invoice was updated | changed field (pattern) |
invoice.deleted | An invoice was deleted | None |
appointment.created | An appointment was created | None |
appointment.updated | An appointment was updated | changed field (pattern) |
appointment.deleted | An appointment was deleted | None |
service.created | A service was created | None |
service.updated | A service was updated | changed field (pattern) |
service.deleted | A service was deleted | None |
Meetings are called Events in Zoho's API, so their API name is Events.
- Changed field is on every
*.updatedevent. It matches the API name of a field that the update changed, such asLead_StatusorOwner. It's a pattern, such asLead_*. Case matters. It's optional. - Moved to stage is on
deal.updated. It matches updates whose newStagevalue matches, such asClosed Won. It's a pattern, and case matters. It's optional. It uses the new field values that Zoho sends with each update. An update that arrives without a newStagevalue doesn't match.
Each event carries the module, the record ID, the operation, and for updates the changed fields with their new values. It doesn't carry the whole record, so the agent reads the record from Zoho. When one action changes several records, such as a mass update, each record starts its own run. Actions on related records, such as a note added to a deal, don't send an event for the deal.
Zoho doesn't sign notifications. Each one carries a random token that Helios sets on the channel, and Helios rejects notifications without it. Zoho also returns that token when a channel is read or changed through /crm/v8/actions/watch. Helios removes it from those responses before an agent sees them, and from the events it passes to workflows.
An agent that updates a record can start another run of that module's *.updated event, such as deal.updated. An agent that creates a record, such as a task, can start a *.created run. Filter on a field the agent doesn't change, or say in the prompt which changes to ignore. See Guarding against events you don't want.
Check that it works
- The connection: after you approve access, the connection's status shows Connected. Error means Zoho rejected the token. See Common errors.
- A trigger:
- Add
lead.createdto a workflow with no filters. - Create a test lead in Zoho CRM.
- Check that a run starts. Then open the connection in Helios and click Webhook events to see the event.
- Add
Common errors
| What you see | Cause | Fix |
|---|---|---|
invalid_client from Zoho | The client ID or secret is wrong, or the client is in another data center with its own secret for yours | Check the values on the Client Secret tab. For another data center, turn on Use the same OAuth credentials for all data centers |
invalid_redirect_uri from Zoho | The redirect URI on the client doesn't match | Add https://api.heliosapp.com/integrations/zoho_crm/oauth_callback to the client |
This Zoho account is in another data center. Set Base URL to that data center's API domain, such as https://www.zohoapis.eu, or clear it, and connect again. | Base URL names a different data center than your account | Set Base URL to your data center from the table, or clear it, and connect again |
Set the base URL to your Zoho API domain, such as https://www.zohoapis.eu | Base URL isn't a Zoho API domain | Use a Base URL from the table |
Zoho returned an unknown accounts server | Your Zoho account is in a data center that isn't in the table above | Helios supports only the data centers in the table |
Authorize the Zoho CRM OAuth app first | The approval in Zoho wasn't finished | Open the connection and connect again |
| The connection's status shows Error after it worked | The refresh token was revoked, or invalidated because the user has more than 20 | Connect again |
Zoho CRM did not create the notification channel: … | Zoho refused the channel. The message says why | Fix the cause, then save the connection again |
| An event shows as unavailable in the trigger picker | The organization doesn't have that module, or Zoho refused to watch it. The picker shows the reason | Turn on the module in Zoho CRM if your edition includes it, then save the connection again |
NO_PERMISSION from Zoho in a run | The profile of the user who approved access doesn't allow that action | Give the user's profile the permission in Zoho CRM, or connect as a user who has it |
OAUTH_SCOPE_MISMATCH from Zoho in a run | The token doesn't have the scope the call needs, such as an admin scope without Admin access | Check Admin access through Manage and connect again |
| No run starts after an event | The channel wasn't created or has ended, the module is unavailable for the organization, or the filters don't match | Save the connection again, check the trigger picker, and remove filters to test |
Limits
- API credits: Calls count toward your organization's Zoho API limits. See Zoho's API limits.
- Notification channels: a channel lasts at most one week. Helios replaces it every five days.
Last updated on
Sentry
The Sentry integration lets Helios agents read and change issues, events, projects, releases, and alerts through Sentry's REST API, and start workflows from supported Sentry webhook events.
Discord
The Discord integration lets Helios agents interact with Discord to read/send messages, manage channels, automate community interactions and much more.