Platform
Chatbot Builder Bulk Messaging Team Inbox Mini CRM API & Webhooks AI Integration WhatsApp Flows
Industries
E-commerce & D2C Real Estate Education Healthcare Finance & BFSI Logistics Hospitality Retail
Integrations
Learn
Learning Hub Help & Docs Connect Guides Automation Codex Blog Message Templates
Pricing Get Started →
HomeConnect › Connect Zoho CRM to WhatsApp
Zoho CRM Integration Guide · CRM / Sales

Connect Zoho CRM to WhatsApp

Pull live contact and lead data from Zoho CRM into a WhatsApp chatbot. When a prospect messages you, search by their phone number, fetch their lead status and assigned owner, and reply with personalised context in seconds.

Published 22 June 2026  ·  9 min read  ·  CRM / Sales

Before following this guide, read the External API Request step foundation guide. It covers every field in the step interface so this guide can focus on Zoho-specific values.

Two critical Zoho-specific differences from other CRMs

1. The auth header is Zoho-oauthtoken, not 'Bearer'. 2. The API domain depends on your data centre. Indian accounts must use zohoapis.in, not zohoapis.com. Getting either wrong returns authentication errors with no helpful message.

Step 1: Confirm your data centre

Before generating tokens, identify which Zoho data centre your account is on. This determines every URL you use.

Data centreAuth URLAPI base URLHow to confirm
India (most Indian accounts)accounts.zoho.inwww.zohoapis.inZoho CRM > Setup > Developer Space > API. Check the listed API domain.
USaccounts.zoho.comwww.zohoapis.comDefault for accounts created on zoho.com
EUaccounts.zoho.euwww.zohoapis.euAccounts created on zoho.eu
Australiaaccounts.zoho.com.auwww.zohoapis.com.auAccounts created on zoho.com.au

If you are an Indian business that signed up at zoho.com/in or zoho.in, your data centre is almost certainly India (.in). Verify in Setup > Developer Space > API before generating tokens.

Step 2: Create a Self Client and generate tokens

A Zoho Self Client lets you generate an OAuth token for your own account without needing a hosted redirect URL. This is the simplest path for internal integrations like a WA.Expert bot.

1
Go to api-console.zoho.in (use your data centre domain). Click GET STARTED.
2
Click Self Client then CREATE NOW. Click OK. Copy the Client ID and Client Secret shown under the Client Secret tab.
3
Click Generate Code tab. In the Scope field enter: ZohoCRM.modules.contacts.READ. Set expiry to 10 minutes. Click CREATE. Copy the grant code.
4
Exchange the grant code for tokens by making a POST request (shown below). You get an access_token (1 hour) and a refresh_token (permanent). Store both securely.
Exchange grant code for access and refresh tokens (India data centre)
POST https://accounts.zoho.in/oauth/v2/token
Content-Type: application/x-www-form-urlencoded

Body (form fields):
  client_id     = YOUR_CLIENT_ID
  client_secret = YOUR_CLIENT_SECRET
  grant_type    = authorization_code
  code          = YOUR_GRANT_CODE

Response:
{
  "access_token":  "1000.875cf8ea310ae70c6fb26e25a5a48df0.be3bc88...",
  "refresh_token": "1000.ce79a5110c4097744b17aecbb95dcfeb.db3167...",
  "api_domain":    "https://www.zohoapis.in",
  "token_type":    "Bearer",
  "expires_in":    3600
}

Save BOTH tokens. The access_token lasts 1 hour.
The refresh_token is permanent until revoked.
Refresh tokens before they expire

Zoho access tokens expire after 3,600 seconds (1 hour). For a production WhatsApp bot, set up a refresh step that POSTs to accounts.zoho.in/oauth/v2/token with grant_type=refresh_token before each CRM lookup. Store the latest access_token in your automation and update it each time it is refreshed.

Official docs

Zoho Self Client token generation: zoho.com/accounts/protocol/oauth/self-client

Step 3: Fill in the External API Request step

The most practical WhatsApp use case is searching Zoho CRM by phone number, since the customer's WhatsApp number is already available in the conversation. In your chatbot flow, store the customer's number as {{customer_phone}} and add an External API Request step:

External API Request Step — WA.Expert
Select Method
GET
Request URL
https://www.zohoapis.in/crm/v8/Contacts/search?phone={{{{customer_phone}}}}&fields=First_Name,Last_Name,Email,Mobile,Lead_Status,Account_Name
Select Auth Type
No Auth (Zoho-oauthtoken in header below)
Header Parameters
AuthorizationZoho-oauthtoken 1000.875cf8ea310ae70c6fb26e25a5a48df0...
Content-Typeapplication/json
Select Body Type
None (GET requests carry no body)
Choose Response Type
JSON

Field-by-field breakdown

FieldValueNotes
Select MethodGETSearching existing contacts.
Request URLhttps://www.zohoapis.in/crm/v8/Contacts/search?phone={{{customer_phone}}}&fields=...Use your data centre domain (.in for India). ?phone= searches the Phone field. ?fields= lists what to return.
Select Auth TypeNo AuthZoho auth goes in the Authorization header below.
AuthorizationZoho-oauthtoken 1000.875cf8...IMPORTANT: the prefix is 'Zoho-oauthtoken', not 'Bearer'. Paste the access_token value from Step 2 after the prefix and a space.
Content-Typeapplication/jsonStandard header for Zoho CRM API requests.
Select Body TypeNoneGET requests carry no body.
Choose Response TypeJSONZoho returns structured JSON.

Step 4: Map the response to WhatsApp variables

A successful Zoho CRM contact search response looks like this:

Zoho CRM API v8 — GET /Contacts/search?phone=... response
{
  "data": [
    {
      "First_Name": "Priya",
      "Last_Name": "Sharma",
      "Email": "priya@example.com",
      "Mobile": "9820000001",
      "Lead_Status": "Contacted",
      "Account_Name": {
        "name": "Sharma Textiles",
        "id": "3652397000000411001"
      },
      "id": "3652397000009851001",
      "Owner": {
        "name": "Ravi Kumar",
        "email": "ravi@business.com",
        "id": "3652397000000411002"
      }
    }
  ],
  "info": {
    "count": 1,
    "more_records": false
  }
}
Response data is in an array under 'data'

Zoho wraps results in a 'data' array even for a single match. Map your variables using data[0].fieldname notation. If no contact is found, the response is an empty 'data' array. Add a conditions branch in your chatbot to handle this.

Map these response paths to variables in the External API Request step:

Variable nameResponse pathExample value
first_namedata[0].First_NamePriya
last_namedata[0].Last_NameSharma
emaildata[0].Emailpriya@example.com
lead_statusdata[0].Lead_StatusContacted
companydata[0].Account_Name.nameSharma Textiles
assigned_todata[0].Owner.nameRavi Kumar
contact_iddata[0].id3652397000009851001

Field names in Zoho CRM use PascalCase with underscores (First_Name, Lead_Status). These are the API names, not the display labels shown in the Zoho UI.

Keep the WhatsApp reply in the free service window

If the contact messaged you first within the last 24 hours, your reply is a free service conversation. Use that window. For proactive outbound follow-up triggered by Zoho data, use an approved Utility or Marketing template.

Worked example: lead status bot

Chatbot flow — Zoho CRM contact lookup by WhatsApp number
Customer messages your WhatsApp number.
WA.Expert captures their phone as {{customer_phone}} = "9820000001".

External API Request step:
GET https://www.zohoapis.in/crm/v8/Contacts/search
  ?phone=9820000001
  &fields=First_Name,Lead_Status,Account_Name,Owner
Authorization: Zoho-oauthtoken 1000.875cf8...

Response mapped:
first_name   = "Priya"
lead_status  = "Contacted"
company      = "Sharma Textiles"
assigned_to  = "Ravi Kumar"

Bot replies:
"Hi Priya, good to hear from you.
You are registered with us as a contact for Sharma Textiles.
Your account status: Contacted.
Your account manager is Ravi Kumar.

Reply CALLBACK to request a call back from Ravi."

Refreshing an expired access token

Zoho access tokens expire after 1 hour. Use the refresh token to get a new one without repeating the full grant-code flow:

Refresh an expired Zoho access token
POST https://accounts.zoho.in/oauth/v2/token
Content-Type: application/x-www-form-urlencoded

Body (form fields):
  client_id     = YOUR_CLIENT_ID
  client_secret = YOUR_CLIENT_SECRET
  grant_type    = refresh_token
  refresh_token = YOUR_REFRESH_TOKEN

Response:
{
  "access_token": "1000.NEW_TOKEN_HERE...",
  "api_domain":   "https://www.zohoapis.in",
  "token_type":   "Bearer",
  "expires_in":   3600
}

Store the new access_token. The refresh_token stays the same.

Troubleshooting

SymptomLikely causeFix
Authentication failed / invalid_clientWrong data centre URL or using 'Bearer' instead of 'Zoho-oauthtoken'Confirm your data centre (Setup > Developer Space > API). Use zohoapis.in for Indian accounts. Change Authorization header to 'Zoho-oauthtoken YOUR_TOKEN'.
AUTHENTICATION_FAILURE in response bodyAccess token expired (1 hour limit)Use the refresh token to get a new access token. Update the stored token in WA.Expert before the next CRM lookup.
No data / empty arrayContact not found by phone numberZoho matches exactly. Try searching by Mobile field too: ?phone=9820000001 searches the Phone field. Use ?criteria=(Phone:equals:9820000001)or(Mobile:equals:9820000001) to search both.
Invalid scope error when generating grant codeWrong scope nameThe scope must match exactly: ZohoCRM.modules.contacts.READ. Check Zoho's API documentation for the exact scope name for other modules.
Field not in responseField not included in ?fields= parameterAdd the field's API name to the ?fields= comma-separated list. Find API names in Zoho CRM Setup > Customisation > Modules > Contacts > Fields.
Grant code expiredGrant codes expire in 10 minutesGenerate a new grant code from the Self Client in api-console.zoho.in and exchange it immediately.

Common questions

Why does Zoho use 'Zoho-oauthtoken' instead of 'Bearer'?
+
Zoho uses its own authorization scheme name. The correct header is: Authorization: Zoho-oauthtoken YOUR_ACCESS_TOKEN. Using 'Bearer' returns a 401 error. This is the most common mistake when connecting Zoho to external tools.
What is the correct Zoho API URL for Indian accounts?
+
Indian accounts use zohoapis.in as the API domain. The full URL is https://www.zohoapis.in/crm/v8/Contacts. Using the US .com domain returns authentication errors for Indian accounts.
Zoho access tokens expire in 1 hour. How do I handle this?
+
Use the refresh token to get a new access token by POSTing to accounts.zoho.in/oauth/v2/token with grant_type=refresh_token. Store the new access_token and use it for subsequent CRM calls.
What is a Zoho Self Client?
+
A Self Client is an OAuth client type for integrations where you own the Zoho account. No redirect URI is needed. You generate the grant code in the API console and exchange it for tokens manually. Simplest path for internal integrations.
What fields are available in the Zoho CRM Contacts response?
+
Depends on the ?fields= parameter. Common ones: First_Name, Last_Name, Email, Phone, Mobile, Lead_Status, Account_Name, Owner. Find API names in Zoho CRM Setup > Customisation > Modules > Contacts > Fields.
Does this incur extra WA.Expert charges?
+
The External API Request step counts as one automation action per call. On the Complete plan this is included. On Starter, extra action packs apply from Rs. 49 per 1,000 actions.

Connect Zoho CRM to WhatsApp today

Free trial, no credit card required. And if you ever get stuck, we are the only platform in India that answers you live on WhatsApp.

Start Free Trial → Book a Demo
1