Zoho CRM is Fabric's SaaS source: a database-free connector that reads CRM modules over the REST API using OAuth2. Change capture is polling, not log-based — each cycle fetches records modified since the last cursor, plus a separate feed of deleted IDs.
Prerequisites
The OAuth application
Fabric connects through a single shared Server-based Application registered in the Zoho API console, with Multi-DC support enabled. The client ID and secret are held as platform secrets, not typed into the source form.
For that application:
- Register the redirect URI
https://<fabric-host>/api/sources/zoho/oauth/callback/(or the configured callback URL). It must match exactly, or the token exchange fails. - Request the scopes
ZohoCRM.modules.ALLandZohoCRM.settings.ALL— the settings scope powers module and field discovery.
Self-hosted operators
The Zoho user
The user who authorizes the connection must be able to approve those scopes. There is no region to pick — the data center is discovered during the OAuth handshake.
Connecting
Click Connect to Zoho. The browser opens Zoho's consent screen and returns you to the wizard with the connection marked Connected. Nothing is saved until you create the source, and the refresh token written by the callback is stored write-only. On an existing source the same button becomes Reconnect to Zoho, which rewrites the token in place without disturbing the synced tables.
Connection fields
| Field | Required | Default | Notes |
|---|---|---|---|
| Connector name | Yes | — | Unique across sources. |
| Edition | Yes | free | Free (5,000 credits/day), Standard or Professional (~100,000), or Enterprise (up to 5,000,000). Drives the preflight credit check. |
| Zoho connection | Yes on create | — | The Connect / Reconnect OAuth button. |
| Modules | No | all standard modules | Comma-separated, case-sensitive module API names. Fetch modules populates a multi-select from the live account. |
| Polling interval (ms) | Yes | 300000 | How often modules are polled. Every cycle costs API credits. |
| Page size | Yes | 200 | Records per API page; Zoho caps this at 200. |
Credits and polling
Zoho meters API calls with a rolling daily credit budget. Before a source is created — and whenever its polling shape changes — Fabric estimates the cost per poll and refuses a configuration that would exceed the edition's budget:
cost_per_poll = Σ modules (1 + deleted_pages + record_pages)
daily_cost = cost_per_poll × polls_per_dayRaise the polling interval or select fewer modules when the estimate is too high.
How it replicates
- Snapshot: each module pages through all records (
op=r) and seeds its cursor at the snapshot start, so edits made mid-snapshot are re-read. - Incremental: an inclusive
If-Modified-Sincepull, deduplicated by record ID and advanced to the maximum modified timestamp. - Deletes: a separate deleted-records feed emits tombstone rows (
op=d). A cursor older than 60 days forces a module re-snapshot instead of silently restarting. - Access tokens live about an hour; Fabric refreshes them in-process on a 401.
Gotchas
Watch out
- A configuration over the credit budget is refused at save, naming the budget — this is the most common Zoho setup failure.
- Unsupported modules (UI-only tabs, anything not exposed by the API) are refused as such, not misreported as a scope error.
- Multi-select and multi-user lookup values appear only on per-record fetches and land as null in list pulls; inventory subforms are excluded and shipped as flat rows.
- An expired or already-used OAuth nonce reports a reconnect requirement rather than failing silently.