aethexDocs
Zoho CRM logo
CRM

Zoho CRM

Connect your Zoho CRM and your voice agents can recognise the caller, read their contacts, leads, and open deals, keep the record current, and file answered calls on the contact, all during the call in your own Zoho.

How it works

Connect your Zoho CRM once, choose which agents may use it, and give each one a read or a write grant. Aethex stores the connection encrypted and turns your CRM into a small set of actions an agent can call mid-call, choosing for itself when each is needed. The grant is the whole story: read lets an agent look things up, write lets it change your CRM and have its answered calls filed for you. Everything below follows from that one choice.

AETHEXyour agentREAD GRANTLook up the callerRead contacts, leads and dealsWRITE GRANTKeep a record currentLog the callautoreadwriteWrite includes everything read can do. The call log follows the write grant.

EU data centres only

Zoho shards its customers across independent data centres — US, EU, India, Australia, China, Japan, Canada and Saudi Arabia — and each one runs its own accounts server. Aethex connects through the EU one, accounts.zoho.eu, so this integration works for organisations whose Zoho account lives in the EU data centre. Check yours by signing in to Zoho CRM and reading the address bar: an EU organisation is served from a .eu domain.

Heads up
Check this before you start. A refresh token is only redeemable at the accounts server that issued it, so Zoho rejects a non-EU customer's consent at its own sign-in screen — before Aethex sees the request. Nothing half-connects, but the consent screen cannot be made to succeed by retrying it.
STEP 01

Connect your Zoho CRM

Zoho connects over OAuth, so you never handle an API key. Call POST /api/v1/integrations/zoho/authorize with a key that carries the integrations:write scope, and it returns an authorize_url. Send the customer's browser there: they sign in to Zoho and approve one consent screen granting access to their contacts, leads, deals, calls, and notes. Zoho then redirects back to Aethex, the connection is created, and the browser lands back on your integrations page. Aethex keeps the connection alive from then on, refreshing the token in the background.You get one active Zoho connection per workspace, and connecting again replaces it. Re-consenting carries your settings across, the narrowed tools and the display name, but not your agent grants: a fresh consent can land on a different account, so Aethex will not silently repoint your agents. Grant them again afterwards.

Note
The consent screen is where access is granted, so the account that approves it is the account your agents will read and write. Approve it as the Zoho user whose contacts, leads, and deals the agent should see, and whose access rules should bound what it can do.
Start the OAuth connect flow
bash
# 1. Start the connect flow. Returns the Zoho consent URL.
curl -X POST https://api.aethexai.com/api/v1/integrations/zoho/authorize \
  -H "X-API-Key: $AETHEX_API_KEY"

# Response:
# { "authorize_url": "https://accounts.zoho.eu/oauth/v2/auth?client_id=...&state=..." }

# 2. Send the customer's browser to authorize_url. They sign in to Zoho and
#    approve one consent screen. Zoho then redirects back to Aethex, the
#    connection is created, and the browser lands on your integrations page.
STEP 02

Grant it to agents

Connecting stores the connection; it does not hand it to anything. A connection with no agent is inert: no call sees its tools and nothing is written to your CRM. Grant it per agent with PUT /integrations/{id}/agents. That PUT replaces the whole set, so send every agent that should keep access, not just the one you are adding. Start at read; move an agent to write only when you want it changing records and filing calls.

Grant an agent
bash
curl -X PUT https://api.aethexai.com/api/v1/integrations/$CONNECTION_ID/agents \
  -H "X-API-Key: $AETHEX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agents": [
      { "agent_id": "<agent-uuid>", "access": "read" }
    ]
  }'
STEP 03

What an agent can do

What an agent can reach is decided when the call is assembled: an action outside its grant is never offered to the model, so a read-only agent has no way to change anything. These are the tools, and the grant each one needs.

ToolWhat it doesGrant
zoho_lookup_contactFinds the caller by phone or email across your Contacts and Leads in one result, so the agent can greet them by name and pick up where the last conversation left off. Matches on both the phone and mobile fields.read
zoho_get_contactReads the full detail of one Contact or Lead you already hold the id for, when the agent needs more than the caller lookup returns.read
zoho_list_stagesLists the pipeline stages your CRM uses for Deals or Leads, so the agent knows the pipeline it is working in.read
zoho_search_dealsFinds the caller's open deals by contact, name, or stage, so the agent can talk to what is actually in flight.read
zoho_record_callerCreates a new Contact, or a Lead when a company name is given, with the number they called from already on the record. Returns the new record id.write
zoho_update_contactEdits a specific Contact or Lead you already hold the id for. Only the fields you send change; the rest stay as they were.write
zoho_add_noteAttaches a note to a Contact, Lead, or Deal, for a detail the caller gives that belongs on the record rather than in the call log.write
zoho_move_lead_stageMoves one Lead or Deal to a different pipeline stage. Off by default; enable it per connection with config.enabled_tools.write, opt-in
Note
zoho_move_lead_stage is opt-in, since a stage change is a decision you should choose explicitly. To turn it on, send config.enabled_tools with the full list of tools you want the connection to expose (it is an exact allowlist, not an addition to the defaults). Keep zoho_log_call in that list, or the automatic call logging below stops.

Automatic call logging

When a call ends, Aethex looks the caller up and files it as a call activity on their Contact or Lead: the subject, direction, start time, duration, and a short summary of what was said. It needs no tool call and no prompt.

Tip
It follows the write grant, so it happens for agents you granted write and not for read-only or ungranted ones. And it only writes on an unambiguous match, so a number that matches two records is left for a human rather than filed on the wrong one. Browser test calls have no number to match on and are excluded, so to see logging end to end, place a real call from a number that belongs to exactly one record, with an agent you granted write.

Import contacts as call lists

A Zoho connection can also seed call lists from your CRM, without exposing your whole org. List what you can import with GET /integrations/{id}/imports/entities — Contacts and Leads, and only the ones this connection can actually read — see the safe fields with GET /integrations/{id}/imports/fields?entity=Contacts, preview a validated sample with POST /integrations/{id}/imports/preview, and read paged rows with POST /integrations/{id}/imports/page. Both Phone and Mobile are offered as dial sources, in that order of precedence. Sensitive fields such as bank details, tokens and national ids are never offered, and the flow is read-only until you run the import.

Note
Leads are read as Zoho reads them by default: unconverted only. A converted lead is already a Contact, so importing both would dial the same person twice.

Security

The OAuth token is encrypted at rest and never returned by any endpoint. Aethex talks to Zoho over public HTTPS, does not follow redirects, and times each request out at 9 seconds. Read and write grants are enforced per agent, and the scopes you approved on the consent screen still apply on top, so a grant can only narrow what that Zoho account could already do. The connection is scoped to your workspace: no other tenant can list it, grant it, or reach it.

Errors

Connect and tool calls surface these statuses.

401Credential rejected

Zoho rejected the access token, most often because consent was revoked in Zoho or the token can no longer be refreshed.

Reconnect to run the consent flow again, then re-grant your agents.

403Access denied

The approved consent does not cover the operation the agent tried, so Zoho refused it.

Reconnect and approve the full consent screen, which grants contacts, leads, deals, calls, and notes.

404Not found

The connection is not this workspace's or is no longer active, or an agent_id on the grant call is not one of your agents.

Check the connection id, and that every agent_id is an agent on this tenant. A foreign id is deliberately indistinguishable from a missing one.

422Unusable request

The provider name was not recognised on the connect call.

Read the message; it names the specific problem. Use zoho as the provider.

429Too Many Requests

The per-tenant connect rate limit was exceeded.

Back off and retry after the Retry-After window. Connecting is a one-time setup, so this usually means a retry loop worth fixing.

503Service unavailable

Zoho was unreachable, the encryption key is not configured, or the connect state store is offline.

Transient; retry shortly.

Notes and limits

A few things worth knowing before you plan around them.

LimitDetail
One connection per workspaceA workspace holds one active Zoho connection, so connecting a second account replaces the first and takes its agent grants with it.
Phone is not a unique keyAethex matches on the phone and mobile fields, and returns ambiguous matches as candidates for the agent to disambiguate rather than guessing which record the caller is.
Reconnect to widen accessThe token carries exactly the scopes you approved. If you need the agent to reach more of your CRM, reconnect and approve the fuller consent; a re-consent carries your settings across but not your agent grants, so grant them again.
Recording is not an atomic upsertRecording a caller is a search-then-write, so two concurrent callers with the same new number can create duplicate records.