Get your dream built 10x faster

How to integrate Zoho CRM with OpenClaw

We build custom applications 5x faster and cheaper 🚀

Book a Free Consultation
4.9
Clutch rating 🌟
600+
Happy partners
17+
Countries served
190+
Team members
Matt Graham, CEO of Rapid Developers

Book a call with an Expert

Stuck on an error? Book a 30-minute call with an engineer and get a direct fix + next steps. No pressure, no commitment.

How to integrate Zoho CRM with OpenClaw

 

Direct answer

 

Install the Zoho CRM integration as a skill through ClawHub, implement Zoho OAuth 2.0 (create a client in Zoho, run an OAuth authorization/code flow to get access + refresh tokens), store those credentials securely in your ClawHub/secret store or an external secret manager, and have the skill call Zoho’s REST API (https://www.zohoapis.com/crm/v2/...) using the access token. Put any stateful or long-running pieces (OAuth callback endpoint, token refresh, webhook receiver, retry queues, persistent logs) outside the agent runtime (a small web service or cloud function), and have the OpenClaw skill invoke that service or read secrets to perform short authenticated API requests. Validate webhooks per Zoho’s docs, respect OAuth scopes, and debug by inspecting API responses, logs, and token lifetimes.

 

Overview — what you need and why

 
  • Zoho side: an OAuth 2.0 client (client_id, client_secret, redirect URI), the correct API base for your region, and any webhook configuration for push updates.
  • OpenClaw side: a skill installed/configured in ClawHub that can make authenticated HTTP calls to Zoho (or call your small, external integration service), and secrets configured for client_id/client_secret/refresh_token/access_token or a reference to an external token store.
  • Runtime split: short-lived API calls can be performed by the skill/agent, but OAuth callback handling, token refresh persistence, webhook handling, retry logic, and storage must live in an external web service or managed server.

 

Architecture and responsibilities (clear separation)

 
  • External web service (recommended): handles the OAuth authorization flow (callback), exchanges code for tokens, stores tokens, exposes secure endpoints the skill can call, receives webhooks from Zoho, and performs heavy lifting (retries, batching, DB writes).
  • OpenClaw skill (inside the agent): contains stateless logic to call Zoho for immediate operations (create/update/read), or calls your external service to perform operations on behalf of the agent. The skill should not be the long-term token holder unless secrets are stored securely and refresh handled.
  • Secrets and configuration: client credentials, API keys, and refresh tokens must be stored in ClawHub secrets or a dedicated secrets manager accessible to the runtime with minimal privileges.

 

Step-by-step integration

 
  • Register the OAuth client in Zoho
    • Create a Zoho OAuth client in the Zoho API Console; set the redirect URI(s) to the external callback you control (not the agent runtime unless it’s publicly reachable).
    • Request only the scopes you need (e.g., ZohoCRM.modules.CREATE, ZohoCRM.modules.UPDATE). Scopes determine what API calls will succeed.
  • Build an OAuth callback endpoint
    • The endpoint accepts the authorization code and exchanges it for access and refresh tokens. Store refresh tokens in a secure store (DB + encryption or secrets manager).
  • Exchange code for tokens (example with curl)
    • Choose the correct Zoho accounts domain for your region (accounts.zoho.com, accounts.zoho.eu, accounts.zoho.in, etc.).
# <b>//</b> Example token exchange (replace domain if needed)
curl -X POST "https://accounts.zoho.com/oauth/v2/token" \
  -d "grant_type=authorization_code" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "redirect_uri=https://your-callback.example.com/oauth/callback" \
  -d "code=AUTHORIZATION_CODE"
  • Persist tokens securely
    • Store refresh_token, client_id, client_secret in a secrets store. Store access_token only if needed and refresh on expiry — do not embed permanent tokens in agent code.
  • Example: simple Node.js express callback that exchanges code and stores tokens
    • Use this pattern as the external service; adapt your storage layer (DB, Vault, ClawHub secrets) rather than in-memory storage.
// <b>//</b> Node.js express minimal callback handler
import express from 'express';
import fetch from 'node-fetch';

const app = express();

app.get('/oauth/callback', async (req, res) => {
  // <b>//</b> req.query.code is the authorization code from Zoho
  const code = req.query.code;
  if (!code) return res.status(400).send('missing code');

  const params = new URLSearchParams();
  params.append('grant_type', 'authorization_code');
  params.append('client_id', process.env.ZOHO_CLIENT_ID);
  params.append('client_secret', process.env.ZOHO_CLIENT_SECRET);
  params.append('redirect_uri', process.env.ZOHO_REDIRECT_URI);
  params.append('code', code);

  const tokenResp = await fetch('https://accounts.zoho.com/oauth/v2/token', {
    method: 'POST',
    body: params
  });

  const tokenJson = await tokenResp.json();
  // <b>//</b> save tokenJson.refresh_token and tokenJson.access_token securely
  // <b>//</b> persist to a DB or secrets manager; do not keep long-term in memory
  // Example: await saveTokensToDB({refresh_token: tokenJson.refresh_token, access_token: tokenJson.access_token});

  res.send('OAuth completed; store refresh token for skills');
});

app.listen(3000);
  • Make API calls to Zoho CRM
    • Use the access token in the Authorization header. If you store only refresh\_token, your external service should perform the refresh-token flow when an access token expires and then return a fresh access token or perform the operation itself.
# <b>//</b> Example: create a Lead with curl
curl -X POST "https://www.zohoapis.com/crm/v2/Leads" \
  -H "Authorization: Zoho-oauthtoken ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "data": [
      {
        "Last_Name": "Doe",
        "First_Name": "Jane",
        "Company": "Acme Inc."
      }
    ]
  }'
  • Refreshing access tokens
    • When the access token expires, exchange the refresh_token with Zoho’s token endpoint (grant_type=refresh\_token). Store the new access token and refresh token if provided.
# <b>//</b> Example refresh token exchange
curl -X POST "https://accounts.zoho.com/oauth/v2/token" \
  -d "grant_type=refresh_token" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "refresh_token=YOUR_REFRESH_TOKEN"

 

Patterns for OpenClaw skills and runtime

 
  • Agent/skill does immediate API calls: If the skill can read secrets (access token or a keyed service account) and the operation is short, it may call Zoho directly.
  • Agent calls external service: Prefer having the agent call your integration microservice (HTTP endpoint). The microservice handles refresh tokens, retries, webhook processing, and DB writes. This keeps the agent stateless.
  • Webhooks: Zoho can send webhooks to your public endpoint. Webhook validation should be performed per Zoho’s documentation; keep the webhook receiver outside the agent so it can persist events and retry on failure.
  • Scheduling/long-running jobs: Use an external scheduler/worker; agents are not durable hosts for scheduled batch jobs.

 

Security and configuration checklist

 
  • Use the correct Zoho accounts domain for region (accounts.zoho.com / .eu / .in).
  • Store client_id and client_secret in a secrets manager (ClawHub secret store or equivalent) — never in source control.
  • Store refresh\_token in an encrypted store and give the agent least privilege access to read secrets needed for runtime.
  • Limit OAuth scopes to what you need; smaller scopes reduce blast radius.
  • Secure your OAuth redirect and webhook endpoints with TLS and IP restrictions if possible.
  • Validate inbound webhooks using Zoho’s recommended method (shared secret or signature) — do not process until verified.

 

Debugging checklist when things fail

 
  • Check HTTP status and response body from Zoho APIs — errors often indicate invalid scope, expired token, or invalid record fields.
  • Inspect the token endpoint responses for refresh failures — refresh token revoked or mismatched client\_secret are common causes.
  • Verify OAuth client redirect URI(s) match exactly what’s registered in Zoho.
  • Ensure the agent or external service is using the correct Zoho accounts domain for your tenant.
  • If webhooks not arriving, verify Zoho configuration, public reachability of your endpoint, and that the webhook sender IPs are not blocked by firewall.
  • Check logs in your external service, ClawHub (skill invocation logs), and Zoho (if available) to correlate timestamps and request IDs.
  • Confirm the skill is actually being invoked (ClawHub/agent logs) and that it has access to necessary secrets.

 

Example end-to-end flow summary

 
  • User registers Zoho OAuth client and configures redirect to https://integration.example.com/oauth/callback.
  • Developer runs authorization flow; external service stores refresh\_token securely.
  • ClawHub skill is configured with a reference to the token store or with a service account that the external service manages.
  • When the skill needs to create a Lead, it either:
    • reads a valid access token from the secret store and calls Zoho directly, or
    • POSTs a small request to your external integration endpoint (recommended), which performs the Zoho API call and returns the result.
  • Webhooks from Zoho hit the external service, which verifies and enqueues events for processing; the skill can query that service for processed results.

Book Your Free 30‑Minute Migration Call

Speak one‑on‑one with a senior engineer about your no‑code app, migration goals, and budget. In just half an hour you’ll leave with clear, actionable next steps—no strings attached.

Book a Free Consultation

Troubleshooting Zoho CRM and OpenClaw Integration

1

Why OpenClaw Zoho CRM Connector fails to refresh OAuth access token (invalid_grant)

Direct answer: An invalid_grant from Zoho means the refresh token the OpenClaw Zoho CRM Connector is presenting is rejected — common causes are a revoked/expired token, a mismatched client_id/client_secret or redirect URI, using the wrong grant_type (e.g., sending an auth code), token rotation/replace, or storing the wrong value in environment variables. In OpenClaw you must ensure the skill’s env vars hold the current refresh token and client credentials and that the runtime uses them when calling Zoho’s token endpoint.

 

What to check

 
  • Refresh token validity: confirm the stored token matches Zoho (tokens can be revoked or rotated).
  • Client creds: client_id/client_secret must match the Zoho app that issued the token.
  • Grant and endpoint: use grant_type=refresh_token against Zoho’s /oauth/v2/token.
  • Env and secrets: validate OpenClaw env vars, secret mounts, and that skill reads them before calls.
  • Clock skew: large time drift can affect some providers.

 

Example refresh call

 
fetch('https://accounts.zoho.com/oauth/v2/token', {
  method: 'POST',
  headers: {'Content-Type':'application/x-www-form-urlencoded'},
  body: new URLSearchParams({
    client_id: process.env.ZOHO_CLIENT_ID,
    client_secret: process.env.ZOHO_CLIENT_SECRET,
    refresh_token: process.env.ZOHO_REFRESH_TOKEN,
    grant_type: 'refresh_token'
  })
}) 
  .then(r => r.json())
  .then(data => console.log(data)) 
  .catch(err => console.error(err)) 
  //check response for error and inspect error_description

2

Why Zoho CRM lead and contact fields not syncing in OpenClaw despite Mapping Rules configured

 

Direct Answer

 

Most likely the Mapping Rules are not being executed or their field names/conditions don’t match Zoho’s API names, or the skill lacks proper Zoho OAuth scopes/credentials so updates fail silently. Check execution, API field names, and auth first.

 

How to diagnose and fix

 
  • Check logs in OpenClaw for mapping execution and Zoho API responses (400/401/403/422).
  • Verify field API names in Zoho (module = Leads or Contacts) — mappings must use Zoho API names, not labels.
  • Confirm OAuth scopes and that the access token in env vars is valid and not expired.
  • Inspect mapping conditions and transform functions; ensure they evaluate true.
  • Test by calling Zoho fields endpoint from your runtime to confirm names:
// Fetch Zoho module fields to verify API names
fetch('https://www.zohoapis.com/crm/v2/settings/fields?module=Leads', {
  headers: { 'Authorization': 'Zoho-oauthtoken ' + process.env.ZOHO_TOKEN }
})
  .then(res => res.json())
  .then(console.log)

3

Why Zoho CRM rejects OpenClaw webhook subscription (validation token mismatch or 403)

Zoho typically rejects an OpenClaw webhook subscription when the validation token or signature you expect doesn't match what Zoho sends, or when your endpoint returns a 403 because of auth, firewall, TLS or permission issues. Fix by verifying the exact token/signature exchange and that the OpenClaw skill endpoint is reachable and authorized.

 

Troubleshooting checklist

 

  • Confirm stored token/secret in your OpenClaw skill environment matches Zoho’s configured value.
  • Inspect raw request (headers and body) in logs to compare sent token or HMAC signature to what your code computes.
  • Return correct response and status code per Zoho docs during validation handshake.
  • Check 403 causes: endpoint auth, missing public TLS, firewall/IP allowlist, or skill permission rules.
  • Capture request traces and retry after fixes; consult Zoho webhook docs for exact header names before changing code.

4

Why OpenClaw creates duplicate records in Zoho CRM — External ID not being sent or Conflict Resolution set to create

Duplicates happen when OpenClaw doesn’t send Zoho’s External ID (so Zoho can’t match incoming data to an existing record) or when the connector’s Conflict Resolution is configured to always create instead of upserting/updating. In short: missing external key or wrong conflict policy causes Zoho to treat every incoming record as new.

 

What to check

 
  • Field mapping — confirm the External ID field is included in the outgoing payload and uses Zoho’s API field name.
  • Connector policy — set Conflict Resolution to upsert/update not create.
  • Credentials & env — ensure the skill has correct permissions and environment variables supplying IDs.
  • Logs — capture the outgoing HTTP body to verify the External ID is present.
Book a Free Consultation

Still stuck?
Copy this prompt into ChatGPT and get a clear, personalized explanation.

This prompt helps an AI assistant understand your setup and guide you through the fix step by step, without assuming technical knowledge.

AI AI Prompt


Recognized by the best

Trusted by 600+ businesses globally

From startups to enterprises and everything in between, see for yourself our incredible impact.

RapidDev was an exceptional project management organization and the best development collaborators I've had the pleasure of working with.

They do complex work on extremely fast timelines and effectively manage the testing and pre-launch process to deliver the best possible product. I'm extremely impressed with their execution ability.

Arkady
CPO, Praction
Working with Matt was comparable to having another co-founder on the team, but without the commitment or cost.

He has a strategic mindset and willing to change the scope of the project in real time based on the needs of the client. A true strategic thought partner!

Donald Muir
Co-Founder, Arc
RapidDev are 10/10, excellent communicators - the best I've ever encountered in the tech dev space.

They always go the extra mile, they genuinely care, they respond quickly, they're flexible, adaptable and their enthusiasm is amazing.

Mat Westergreen-Thorne
Co-CEO, Grantify
RapidDev is an excellent developer for custom-code solutions.

We’ve had great success since launching the platform in November 2023. In a few months, we’ve gained over 1,000 new active users. We’ve also secured several dozen bookings on the platform and seen about 70% new user month-over-month growth since the launch.

Emmanuel Brown
Co-Founder, Church Real Estate Marketplace
Matt’s dedication to executing our vision and his commitment to the project deadline were impressive. 

This was such a specific project, and Matt really delivered. We worked with a really fast turnaround, and he always delivered. The site was a perfect prop for us!

Samantha Fekete
Production Manager, Media Production Company
The pSEO strategy executed by RapidDev is clearly driving meaningful results.

Working with RapidDev has delivered measurable, year-over-year growth. Comparing the same period, clicks increased by 129%, impressions grew by 196%, and average position improved by 14.6%. Most importantly, qualified contact form submissions rose 350%, excluding spam.

Appreciation as well to Matt Graham for championing the collaboration!

Michael W. Hammond
Principal Owner, OCD Tech

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We’ll discuss your project and provide a custom quote at no cost.Â