Connect Zoho CRM
You create a Self Client in Zoho's API Console, grant it two CRM scopes, and paste its Client ID, Client Secret and a grant code into MarqIQ. MarqIQ exchanges that code once for a refresh token and mints its own hour-long access tokens afterwards, so there is nothing to renew by hand. Zoho CRM is a read connection with one exception: the only thing MarqIQ ever creates in Zoho is a custom field on your Leads module, and only when you press the button. If you want to know what you are granting before you start, read How connecting a tool works.
Before you start
Permissions required
You need a Zoho user who can create a Self Client in Zoho's API Console, signed in to the Zoho organisation whose data you want. MarqIQ stores no identifier for which Zoho organisation it is attached to — the saved connection holds the region, its label and the API address, and nothing else — so there is no organisation id on the connection card to check afterwards. Create the Self Client while signed in as the right user, in the right region.
The grant code dies within minutes
A Zoho grant code expires within minutes and is spent the moment MarqIQ exchanges it. Generate it and paste it straight away, in the same sitting. The refresh token MarqIQ derives from it is long-lived, so this is a one-time step rather than something you repeat before each sync.
Plan required
Connecting needs Starter or above. Creating the UTM fields in Zoho needs a paid subscription — on a free plan the Create buttons point at pricing and you map an existing Zoho field by its API name instead. The field and form operations under Tool Operations need Pro or above and do not appear on Starter; a Starter workspace maps its fields from the UTM Field Validation section on the Zoho CRM page.
- Your Self Client's Client ID, from api-console.zoho.com — Zoho ids look like 1000.XXXXXXXX, which is also the placeholder on the connect form.
- Its Client Secret, from the same screen.
- A freshly generated grant code, or a refresh token you already hold. One or the other, not both.
- The region your Zoho account is hosted in. Your own CRM address tells you: crm.zoho.eu is Europe, crm.zoho.in is India, and so on. Zoho documents the regions at www.zoho.com/crm/developer/docs/api/v8/multi-dc.html
Create the Self Client in Zoho
A Self Client issues credentials to your own Zoho organisation with no redirect URL and no sign-in screen. MarqIQ does not run a Zoho sign-in flow for you, so you create the client and hand it over.
Open Zoho's API Console at api-console.zoho.com
Click Add Client.
Choose Self Client.
Open the Client Secret tab.
Both values you need live here. Copy them somewhere you can reach while the connect form is open.
Copy the Client ID.
Copy the Client Secret.
MarqIQ sends this to Zoho every time it renews its access token, not only when you connect. Rotating the secret in the API Console breaks the connection at the next renewal — within the hour — rather than the next time somebody reconnects.
Open the Generate Code tab.
Type both scopes as the scope list: `ZohoCRM.modules.ALL,ZohoCRM.settings.ALL`
`ZohoCRM.modules.ALL` is the one MarqIQ tests at connect, by reading a single lead. `ZohoCRM.settings.ALL` is the one the sync fails on later: MarqIQ asks Zoho which fields exist on a module before it reads a single record, so without that scope the connection succeeds and nothing syncs.
Zoho's `.ALL` also permits creating, editing and deleting records. MarqIQ never uses that half — it issues no create, update or delete against any Zoho record — but the grant allows it.
Pick a duration.
Copy the code.
It expires within minutes. Do not generate it the day before.
Connect it in MarqIQ
Open Integrations in MarqIQ and click the Zoho CRM card.
Zoho CRM sits under the CRM heading. Its own page is headed Zoho CRM.
Paste your client id into Client ID.
Paste your client secret into Client Secret.
Paste the code you generated into Grant code.
If you already hold a refresh token, leave Grant code blank and paste it into Refresh token (instead of a grant code) instead. MarqIQ exchanges a grant code once; a refresh token it keeps and never re-issues.
Choose your region in Data Center.
The options are United States, Europe, India, Australia, Japan, Canada and Saudi Arabia, each labelled with its API host. This is not cosmetic: it fixes both the address MarqIQ reads your CRM from and the address it mints tokens at, and the two are not always the same family — Canada's CRM API sits on zohoapis.ca while its token service sits on zohocloud.ca.
Click Connect Zoho CRM.
MarqIQ exchanges the code, then reads one lead to check the scopes before it saves anything. An empty Leads module still counts as a pass.
If Zoho CRM is already connected the button reads Update credentials instead.
Leave the tab open while the first sync runs.
Connecting starts the sync on its own. The chunk loop runs in your browser, so the status line says "keep this tab open". Close the tab and the run stops where it is. The next sync, manual or scheduled, carries on from the saved cursor.
Read the result line.
A first load finishes with "Fully synced — N records". Later runs say "Up to date — N changes since your last sync". That is one running total across all four modules, not a count per module.
Check the region on the card, not the link
The connection card reads "Zoho CRM (…)" with your region on a Data Center line and an API Base line beside it — www.zohoapis.eu for Europe, www.zohoapis.in for India, and so on. Check that line against the region your CRM really lives in. Do not judge it by the Open Zoho CRM link on the same card: that link always points at crm.zoho.com whichever region you chose.
Note
The very first sync in a new workspace stops on "Creating this workspace's database — it takes under a minute the first time…". MarqIQ waits and retries four times on its own. If it gives up, wait a few minutes and click Sync now.
What comes across
- Leads, Contacts, Accounts and Deals — those four modules, and no others. Activities, Tasks, Calls, Campaigns, Products and Quotes are not read.
- Every visible field on those four, rather than a fixed list. MarqIQ asks Zoho which fields exist, takes each module's standard columns first and then everything else.
- Lookups as their display name, with the id kept beside it, so an account or an owner reads as a name rather than a number. Multi-select picklists arrive joined into one value.
- A deal's won or lost state, read from the stage name: a stage matching "Closed Won" counts as won, one matching "Closed Lost" as lost, and everything else as open. Zoho has no separate status column.
- Zoho's own list of records deleted from those modules, recycle bin and permanent together, so something removed in Zoho stops counting here.
- A sampled record's timeline, while a Field discipline analysis runs: which field changed, from what to what, when, and what kind of writer did it — a workflow rule by name, an import, a web form, a connected app or a person.
- The Leads module's field list again on the Zoho CRM page, to tell you which UTM fields you already have.
The limits, stated where they bite
At most 600 fields per module are synced. Past that ceiling MarqIQ keeps the module's standard columns first, then fields whose names look like source, campaign, UTM, channel, medium, MQL, SQL, score, rating, industry, revenue, employees, status, stage, owner, region, country, segment, reason, lifecycle, program, referrer or partner, then everything else alphabetically. Fields Zoho reports as not visible are skipped, as are subforms, file, image and profile-image uploads, rollup summaries, consent lookups, and lookups that point at several records or modules at once.
Deletions and history are samples, not censuses
Deletions come from Zoho's deleted-records feed, which MarqIQ treats as holding 60 days, and it reads at most 4,000 deleted ids per module per run. If the last delete check was longer ago than that window, the sync says so in its notes. Field discipline reads timelines one record at a time, so it samples up to 60 people and 60 deals rather than the whole account, and how far back a timeline reaches depends on your Zoho edition. Zoho's timeline names the person behind each change; MarqIQ keeps only the kind of writer and never stores or shows that name.
What MarqIQ writes into Zoho
- Custom text fields on your Leads module, 255 characters, and only when you press a button. Create adds that one field; Create N missing adds every missing field in that group — up to nine from a single press.
- Zoho decides the new field's API name. MarqIQ reads it back and stores the mapping in its own database rather than guessing it.
- Nothing else, anywhere in Zoho. No lead, contact, account or deal is created, edited or deleted.
- The only other requests MarqIQ posts to Zoho are the two token calls: the one-time grant-code exchange when you connect, and the renewal that mints its next hour-long access token.
The fields themselves are the seventeen MarqIQ tracks: nine under Most Recent UTM Fields and eight under First Touch UTM Fields. On UTM Field Validation, a green tick means Zoho's Leads module already holds a matching field, a blue tick means MarqIQ has a mapping saved but found no matching field in Zoho, and a red cross with "Not found in Zoho CRM" means neither. The "→" line underneath names the Zoho field it will use.
Take care
UTM Field Validation only ever looks at — and only ever creates on — the Leads module. A UTM field you already keep on Contacts or Deals is still reported as missing.
Tip
To use a field you already have, click Map existing, type its Zoho API name into Zoho field API name (e.g. UTM_Source), and click Save. That costs nothing in Zoho and needs no plan.
What connecting Zoho CRM unlocks
- Source truth — whether the field you report channels from can bear the weight.
- Field discipline — first-touch fields overwritten, stages going backwards, scores typed by hand. Zoho's per-record timeline is what makes this possible at all.
- Audience health, Lead scoring, Funnel and Form fills, each read from the synced records.
- The Integration Audit Report, whose deals section is built from the synced Zoho store as of the last sync.
- Attribution reporting on Zoho deals, once the tracking script is filling your UTM fields.
What it does not unlock
- Forecast accuracy does not run on Zoho. It needs a deal's stage, forecast category and close date history, which MarqIQ reads for HubSpot, Salesforce and Pipedrive today.
- Email and Automations do not run on Zoho. Zoho workflow rules are not listed by the CRM API — open Setup → Automation in Zoho to review those yourself.
- Email analytics, landing pages and web visits are not read, because they are not in Zoho CRM: they live in Zoho Campaigns, Zoho LandingPage and Zoho SalesIQ / PageSense, each a separate product with its own API.
- Zoho web form fills are counted as the leads they create, not as a form feed.
- There is no guided source-tracking setup and no writing onto your live forms. That flow supports HubSpot and Marketo only, so capture the source with the tracking script and hidden fields instead.
- Template Studio does not author for Zoho.
- MarqIQ cannot write a value back into a Zoho record, not even as a proposal you could review. Asking for a change set on Zoho is refused by name: "MarqIQ has no change set for Zoho CRM yet. Changes can be proposed for HubSpot and Marketo."
- MarqIQ cannot link you from a finding into the Zoho record. A Zoho record address needs an organisation id it does not hold, so it lists the records instead of handing you a guessed link that will not open.
If it did not work
"Client ID and Client Secret are required (from your Zoho API Console Self Client)."
Why: One of the two fields is empty, or holds only spaces. MarqIQ trims both before it checks them.
Fix: Open your Self Client in api-console.zoho.com, go to the Client Secret tab, and copy each value into Client ID and Client Secret.
"Paste either a refresh token or a freshly generated grant code."
Why: Both Grant code and Refresh token were left blank. This also catches a re-verification: the form refuses a submission with both blank even when a refresh token is already stored.
Fix: Generate a new grant code in the API Console and paste it into Grant code, or paste a refresh token you hold into Refresh token (instead of a grant code). Fill one, not both.
"The grant code is invalid or has expired — generate a new one (they last a few minutes)."
Why: The code has lapsed, or it was already spent — a code works once. It also appears when the code was generated for one region and sent to another, because MarqIQ posts it to the token service for the Data Center you chose and Zoho's own answer is all it has to go on.
Fix: Check Data Center against the address you use for Zoho CRM. Then generate a fresh code in the API Console, paste it into Grant code, and click Connect Zoho CRM straight away.
"Zoho did not issue a token", followed by the word Zoho used
Why: Zoho answered the grant-code exchange and declined to issue one. MarqIQ quotes Zoho's own error back to you rather than guessing at it. A Client ID or Client Secret that does not belong to the Self Client the code came from is the commonest reason.
Fix: Copy the Client ID and Client Secret again from the Client Secret tab of the Self Client that issued the code. Generate a fresh grant code there, paste it into Grant code, and click Connect Zoho CRM.
"Zoho refused the refresh token for this client — check the Client ID, Client Secret, refresh token and data center."
Why: Zoho declined to mint an access token from the four values you supplied. The commonest cause is a rotated Client Secret; a refresh token belonging to a different Self Client does the same.
Fix: Copy the Client ID and Client Secret again from the Client Secret tab of the Self Client that issued the refresh token. If you cannot tell which client issued it, generate a fresh grant code from that Self Client and leave Refresh token blank.
"The token lacks CRM read scope. Add ZohoCRM.modules.ALL and ZohoCRM.settings.ALL to the Self Client and generate a new grant code."
Why: Zoho answered 403 when MarqIQ read one lead to verify the connection. The credentials are right and the scopes are not.
Fix: Go back to Generate Code in the API Console, type `ZohoCRM.modules.ALL,ZohoCRM.settings.ALL` as the scope list, generate a new code, and connect again. A scope change needs a new code — the old one does not carry it.
The connection saved cleanly and the sync stops in red with "Zoho rejected the token (OAUTH_SCOPE_MISMATCH)"
Why: The Self Client is missing `ZohoCRM.settings.ALL`. The connection test only reads a lead, so it never checks that scope — this is the failure that shows up only after a connection that looked fine.
Fix: Generate a new grant code with both scopes, paste it into Grant code, click Update credentials, then click Sync now.
UTM Field Validation is empty, or the Refresh button returns an error instead of a field list
Why: That screen reads the Leads field list from Zoho, which also needs `ZohoCRM.settings.ALL`. It quotes Zoho's own refusal back to you rather than showing an empty list as though your CRM had no fields.
Fix: Add the settings scope to the Self Client, generate a new grant code, and click Update credentials. Then click Refresh above UTM Field Validation.
The sync finishes but a module you use is missing, with no message on the page
Why: Zoho refused the field list for that module, so MarqIQ skipped it rather than failing the whole run. The note names the module — "Deals: not available in this Zoho account" — and the Zoho CRM page shows one running total instead of a count per module.
Fix: Open Attribution & Journeys and read the line under Connected Data Sources for Zoho. A module you genuinely do not have needs nothing; a module you do have points back at the scopes on the Self Client.
Clicking Create answers "Creating fields in Zoho CRM is a paid feature — upgrade to create them, or map an existing field."
Why: Creating a field inside your own tool is gated by your MarqIQ plan, not by Zoho.
Fix: Move to a paid plan, or click Map existing and type the API name of a Zoho field you already have. Mapping is not gated.
The connect is refused with a message naming the tools you have already connected
Why: Starter includes one tool besides Google Tag Manager, and Starter, Free Trial and Pro allow one tool from the CRM category. The refusal names the tools using the allowance, or the CRM already holding the category.
Fix: Disconnect the other tool, or move up a plan. Reconnecting a tool that is already connected is always allowed, so rotating your Zoho credentials never runs into this.
"This workspace is read-only. Renew the subscription to connect tools."
Why: The subscription has lapsed, or an administrator has set the workspace to read-only. No tool connects in that state.
Fix: Renew the subscription on Subscription in your account settings, then connect Zoho CRM again.
The sync answers "Another sync is already running for this workspace — it will finish on its own."
Why: The scheduled run holds this workspace. Only one sync per tool runs at a time, by design.
Fix: Nothing. Your data is being refreshed right now. The message is shown in green rather than red for that reason.
You disconnected Zoho CRM and want the access gone at Zoho's end too
Why: Disconnecting clears the stored credentials in MarqIQ and marks the connection disconnected. It revokes nothing at Zoho.
Fix: Revoke the Self Client's refresh token yourself in api-console.zoho.com
Next steps
Related articles
Was this article helpful?