Skip to Content
ChannelsZoho CrmZoho CRM — Channel Overview

Zoho CRM — Channel Overview

Researched: May 2026

Contents

  • README.md — This file: overview, what to build, implementation plan

Full deferred-feature notes live at docs/missing-incomplete-features/zoho-crm-channel.md.


Status

Deactivated — removed from the active channel catalogue April 2026. No provider package or import worker exists yet. Note: Zoho Books (accounting) has a separate OAuth callback already wired in channel-oauth.routes.ts; this doc is for Zoho CRM (lead management), which is a distinct product and OAuth app.


Why This Channel

Zoho CRM is widely used by Indian SMBs — Leadmetrics’ core target market. Connecting it transforms Leadmetrics from a content-generation tool into a closed-loop marketing platform: content drives traffic → traffic becomes leads → leads appear in Leadmetrics → agents can attribute which content converted. This is the “content ROI” story that justifies the subscription cost to budget-conscious clients.

Secondary value: agents get real lead context. The blog writer can know that the last 10 leads came in via the “local SEO tips” post and write more content in that vein.


Auth Mechanism

OAuth 2.0 (standard authorization code flow).

  • Auth URL: https://accounts.zoho.{region}/oauth/v2/auth (region: com / in / eu / au)
  • Token URL: https://accounts.zoho.{region}/oauth/v2/token
  • Scopes: ZohoCRM.modules.READ ZohoCRM.modules.WRITE ZohoCRM.users.READ
  • Token refresh: access token expires in 1 hour; refresh token is long-lived

The accounts-server query param returned in the callback determines which regional endpoint to use for all subsequent API calls — same pattern already implemented for Zoho Books in channel-oauth.routes.ts.


What It Enables

CapabilityDetail
Lead importSync Zoho Leads into Leadmetrics Lead + LeadContact tables on connect + nightly schedule
Contact syncOptional: sync Zoho Contacts (warm leads / customers)
Deal pipeline readPull deal stages and amounts to measure revenue attribution
Lead source attributionTag which Leadmetrics content (blog, landing page, social) generated the lead
Two-way status syncUpdate lead stage in Zoho when DM changes status in Leadmetrics (Phase 2)
Insight workerTop lead sources; lead volume trend; conversion rate by content type

Workers Needed

WorkerQueueTrigger
zoho-lead-importer.worker.ts (new)agent__zoho-lead-importerOn channel connect + nightly cron 0 1 * * *
zoho-crm-insights.worker.ts (new)agent__zoho-crm-insightsWeekly

Insight Worker Output (ChannelInsight)

  • Total leads this month vs last month
  • Top 3 lead sources (which Leadmetrics content types convert)
  • Lead-to-deal conversion rate over 30 days
  • Average time from lead creation to first contact
  • Suggested: content topics correlated with highest-converting leads

Implementation Plan

Phase 1 — Connect + Read-only Lead Import

  1. Create packages/providers/zoho/src/zoho-crm.ts:

    • getAuthUrl(callbackUrl, channelId, region) — auth URL with access_type=offline
    • exchangeCode(code, callbackUrl, accountsServer) — returns tokens + accountsServer
    • refreshAccessToken(refreshToken, accountsServer) — region-aware token refresh
    • getLeads(accessToken, accountsServer, page?)GET /crm/v7/Leads with pagination
    • getContacts(accessToken, accountsServer, page?)GET /crm/v7/Contacts
    • verify()GET /crm/v7/users?type=CurrentUser
  2. Add OAuth routes to apps/api/src/routers/channel-connect.ts:

    • GET /zohoCrm/connect → return auth URL (prompt region selection or default to in)
    • GET /zohoCrm/callback → exchange code (capture accounts-server), store tokens + accountsServer in subChannelInfo, close popup
  3. Create packages/agents/src/workers/zoho-lead-importer.worker.ts:

    • Load all tenants with an active Zoho CRM channel
    • Fetch leads from Zoho (paginated, last-modified-since for incremental sync)
    • Upsert into Lead + LeadContact tables; set source: "zoho_crm" + zohoLeadId
    • Record lastSyncAt on the channel
  4. Re-activate seed entry in packages/db/prisma/seed.ts

  5. Create apps/dashboard/src/app/(dashboard)/channels/[id]/ZohoCrmChannelDetail.tsx:

    • Connection status + last sync time
    • Total leads imported; leads this month
    • Recent leads list (last 20)
    • “Sync Now” button

Phase 2 — Two-way Sync + Deal Attribution

  1. Add PATCH /crm/v7/Leads/:id to the provider: update lead stage from Leadmetrics
  2. Zoho webhook endpoint: POST /tenant/v1/zoho-crm/webhook — real-time lead push from Zoho
  3. Lead source attribution: when a landing page form submits, capture utm_source → look up matching SocialPost or BlogPost → link to Lead.sourceActivityId

DB Changes Needed

The existing Lead + LeadContact models (from the lead scoring pipeline) need two new fields:

// Add to Lead model: zohoLeadId String? // Zoho record ID for two-way sync dedup source String? // "zoho_crm" | "landing_page" | "manual" // Add to ConnectedChannel subChannelInfo (JSON): // { accountsServer: "https://accounts.zoho.in", ... }

Seed Entry

// packages/db/prisma/seed.ts — CHANNEL_CATALOGUE { type: "ZohoCRM", name: "Zoho CRM", iconKey: "zoho", description: "Import leads from Zoho CRM and measure content-to-lead attribution.", authenticationType: "oauth2", requiresUrl: false, isActive: true, // change from false categories: ["crm"], },

  • docs/missing-incomplete-features/zoho-crm-channel.md
  • docs/missing-incomplete-features/lead-scoring-nurture.md
  • docs/missing-incomplete-features/twitter-zoho-channel-detail-pages.md
  • packages/tools/src/zoho-books.ts — reference for Zoho API patterns (same OAuth infrastructure)

© 2026 Leadmetrics — Internal use only