Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ This is the recommended way to use Zoho Desk in production workflows: the creden

## Prerequisites

You need a Zoho account with access to the [Zoho API Console](https://api-console.zoho.com) for the same organization your Zoho Desk portal belongs to, and the Zoho Desk **organization ID** for that portal.
You need a Zoho account with access to the Zoho API Console **for your data center**, for the same organization your Zoho Desk portal belongs to, and the Zoho Desk **organization ID** for that portal. See [Know Your Data Center](#3-know-your-data-center) for the console that matches your region.

<Callout type="info">
A Self Client can authenticate against the **US, EU, IN, or AU** accounts server — pick your region with the **Data center** field when you add the credential, or leave it blank for US. Organizations in the JP, CA, SA, CN, or UK data centers are not supported yet. API calls are then routed to the Desk host for that same region, so data residency is honored end to end.
A Self Client can authenticate against the **US, EU, IN, or AU** accounts server — pick your region from the **Data center** dropdown when you add the credential, or leave it unset for US. Organizations in the JP, CA, SA, CN, or UK data centers are not supported yet. API calls are then routed to the Desk host for that same region, so data residency is honored end to end.

The interactive **OAuth** connection is a separate path and remains **US-only** (`accounts.zoho.com`), so a non-US organization can connect only through a Self Client.
</Callout>
Expand All @@ -31,7 +31,7 @@ Zoho Desk **webhooks are a Professional-edition and above feature**. The Zoho De

<Steps>
<Step>
Sign in at [api-console.zoho.com](https://api-console.zoho.com) with the Zoho account that owns the Desk portal
Sign in to the Zoho API Console **for your data center** with the Zoho account that owns the Desk portal — see [Know Your Data Center](#3-know-your-data-center) for the right one. A Self Client is registered in one data center and cannot authenticate against another region's accounts server
</Step>
<Step>
Click **Add Client**, choose **Self Client**, and click **Create** — then **OK** on the confirmation
Expand Down Expand Up @@ -68,20 +68,24 @@ This must be the organization ID of the Desk portal you want the workflows to ac

### 3. Know Your Data Center

Zoho hosts each organization in one data center, and the accounts server that issues tokens is per region. Look at the URL you use to sign in to Zoho Desk and pick the matching code:
Zoho hosts each organization in one data center, and the accounts server that issues tokens is per region. Look at the URL you use to sign in to Zoho Desk and pick the matching region in the **Data center** dropdown:

| Data center | Sign-in domain | Code to enter |
| Sign-in domain | Data center to pick | API Console to create the Self Client in |
| --- | --- | --- |
| United States | `zoho.com` | `us` (or leave blank) |
| Europe | `zoho.eu` | `eu` |
| India | `zoho.in` | `in` |
| Australia | `zoho.com.au` | `au` |
| `zoho.com` | United States (the default when left unset) | [api-console.zoho.com](https://api-console.zoho.com) |
| `zoho.eu` | Europe | [api-console.zoho.eu](https://api-console.zoho.eu) |
| `zoho.in` | India | [api-console.zoho.in](https://api-console.zoho.in) |
| `zoho.com.au` | Australia | [api-console.zoho.com.au](https://api-console.zoho.com.au) |

Organizations in the JP, CA, SA, CN, and UK data centers cannot be connected yet.

<Callout type="warn">
Create the Self Client in the console for **your** data center. Zoho ties a client to the region it was registered in — *"the accounts-server-url is specific to the location (i.e., datacenter) where the client is registered"* — and the multi-data-center setting that would extend a client to other regions is [not available for Self Clients](https://docs.catalyst.zoho.com/en/api/oauth2/register-new-client/). A Self Client created in the wrong console cannot be repointed later; create a new one in the right region.
</Callout>

### 4. Scopes

Sim requests exactly the scopes its Zoho Desk tools and trigger exercise:
Sim requests the Zoho Desk scopes its tools and its webhook trigger exercise — the same list on both connection types:

```
Desk.tickets.READ
Expand All @@ -91,10 +95,11 @@ Desk.agents.READ
Desk.basic.READ
Desk.webhooks.CREATE
Desk.webhooks.DELETE
aaaserver.profile.READ
```

Sim sends this list on every token request, so there is nothing to pre-configure on the Self Client itself. If Zoho rejects the request with an invalid-scope error, the Self Client's owner does not have access to one of the Desk modules above in that organization.
Sim sends this list on every token request, so there is nothing to pre-configure on the Self Client itself. The `aaaserver.profile.READ` scope Sim requests on the interactive OAuth flow is deliberately left off this grant — it is an Accounts *profile* scope, and this grant never calls the Accounts profile endpoint; identity is synthesized from the organization ID. If Zoho rejects the request with an invalid-scope error, the Self Client's owner does not have access to one of the Desk modules above in that organization.

`Desk.webhooks.CREATE` and `Desk.webhooks.DELETE` belong to the trigger, which runs on an OAuth connection only (see [Triggers](#triggers-still-need-oauth) below). They are harmless on a Self Client grant, but a Free or Standard Desk plan may reject them, since webhooks are a Professional-edition feature.

A scope that is granted but insufficient surfaces at run time as a `4xx` from the Zoho Desk API naming the scope problem.

Expand All @@ -118,7 +123,7 @@ Regenerating or revoking the Self Client in the Zoho API Console invalidates the
{/* TODO(screenshot): Zoho Desk integration page with the Add Self Client connect option */}
</Step>
<Step>
In the **Add Zoho Desk Self Client** dialog, paste the **Client ID**, the **Client secret**, and the numeric **Organization ID**. Set **Data center** to your region (`us`, `eu`, `in`, or `au`) — leave it blank for US. Optionally set a display name and description
In the **Add Zoho Desk Self Client** dialog, paste the **Client ID**, the **Client secret**, and the numeric **Organization ID**. Pick your region from the **Data center** dropdown — leaving it unset uses the United States. Optionally set a display name and description

{/* TODO(screenshot): Add Zoho Desk Self Client dialog with all fields filled in */}
</Step>
Expand Down Expand Up @@ -153,10 +158,10 @@ Access tokens minted from a Self Client live for one hour and there is **no refr
<FAQ items={[
{ question: "Why a Self Client instead of OAuth?", answer: "A Self Client authenticates as your Zoho organization, not as a person — nothing expires when someone leaves or their login lapses. Sim mints short-lived tokens from the stored client ID and secret whenever a workflow runs." },
{ question: "Where do I find the Organization ID?", answer: "In Zoho Desk, go to Setup (gear icon) → Developer Space → API. The numeric Organization ID shown there is the value to paste. This is expected to be the same ID that Zoho Desk API calls send in the orgId header; if Zoho rejects it with missing_org_info, paste the full ZohoDesk.<your-org-id> value instead." },
{ question: "Zoho rejects my credentials with invalid_client — why?", answer: "Either the client ID or secret was mistyped, or the client you created is not a Self Client. Only Self Clients support the client-credentials grant — in the Zoho API Console, Add Client → Self Client. Copy both values from the client's Client Secret tab." },
{ question: "Zoho rejects my credentials with invalid_client — why?", answer: "Either the client ID or secret was mistyped, the client you created is not a Self Client, or the Self Client was created in a different data center's API Console than the Data center you selected. Only Self Clients support the client-credentials grant — in the Zoho API Console, Add Client → Self Client. Copy both values from the client's Client Secret tab, and create the client in the console for your region." },
{ question: "Zoho returns missing_org_info or rejects the organization — why?", answer: "Zoho could not resolve a Desk organization from the ID you pasted. Re-copy the numeric Organization ID from Setup → Developer Space → API in the Desk portal you want to use. If your Zoho account has multiple Desk portals, make sure it is the ID of the right one." },
{ question: "Can I use a Self Client with a non-US Zoho account?", answer: "Yes, for the US, EU, IN, and AU data centers. Set the Data center field to us, eu, in, or au when you add the credential, and Sim mints tokens against that region's accounts server and calls the Desk host in the same region. Leaving it blank means US. The JP, CA, SA, CN, and UK data centers are not supported yet, and the interactive OAuth connection remains US-only." },
{ question: "I picked the wrong data center — what happens?", answer: "The region's accounts server does not know your organization, so Zoho rejects the token request and Sim reports that it could not authenticate. Edit the credential and set the Data center to the region whose domain you sign in to Zoho Desk with." },
{ question: "Can I use a Self Client with a non-US Zoho account?", answer: "Yes, for the US, EU, IN, and AU data centers. Pick your region from the Data center dropdown when you add the credential, and Sim mints tokens against that region's accounts server and calls the Desk host in the same region. Leaving it unset means US. Create the Self Client in that region's API Console too. The JP, CA, SA, CN, and UK data centers are not supported yet, and the interactive OAuth connection remains US-only." },
{ question: "I picked the wrong data center — what happens?", answer: "The region's accounts server does not know your Self Client, so Zoho rejects the token request and Sim reports that it could not authenticate. Edit the credential and pick the region whose domain you sign in to Zoho Desk with — and check that the Self Client itself was created in that same region's API Console, since a client cannot authenticate against another region." },
{ question: "Why doesn't my Zoho Desk trigger work with the Self Client?", answer: "The trigger provisions a webhook subscription in your Desk organization, and that path runs against a personal OAuth connection only. Connect Zoho Desk through OAuth for triggers. Separately, Zoho Desk webhooks require a Professional-edition plan or above — they are unavailable on Free and Standard." },
{ question: "How do I rotate the credentials?", answer: "Regenerate the client secret on the Self Client's Client Secret tab in the Zoho API Console, then update the credential in Sim with the new secret. The old secret stops working as soon as it's regenerated, so update Sim promptly." },
]} />
20 changes: 15 additions & 5 deletions apps/docs/content/docs/en/integrations/zoho_desk.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,14 @@ List tickets from a Zoho Desk organization with optional filters. Returns a list
| --------- | ---- | -------- | ----------- |
| `apiDomain` | string | No | Zoho Desk data-center REST base URL |
| `orgId` | string | Yes | Zoho Desk organization ID |
| `from` | number | No | Pagination start index \(0-based, max 4999\) |
| `limit` | number | No | Number of tickets to return \(1-100, default 10\) |
| `from` | number | No | Pagination start index \(0-based\) |
| `limit` | number | No | Number of tickets to return \(1-100\) |
| `departmentIds` | string | No | Filter by department ID \(comma-separated for multiple\) |
| `status` | string | No | Filter by status, including custom statuses. Comma-separate to match multiple \(e.g. "Open,On Hold"\) |
| `priority` | string | No | Filter by priority. Comma-separate to match multiple \(e.g. "High,Urgent"\) |
| `assignee` | string | No | Filter by assignee: an agent ID, or "Unassigned". Comma-separate to match multiple. |
| `channel` | string | No | Filter by origin channel, spelled as your portal spells it. Comma-separate to match multiple. |
| `receivedInDays` | number | No | Only tickets whose last customer response was within the last 15, 30, or 90 days \(Zoho filters on customerResponseTime, despite the name\) |
| `sortBy` | string | No | Sort field: createdTime, customerResponseTime, or responseDueDate. Prefix with - for descending. |
| `include` | string | No | Comma-separated related data to embed. Allowed: contacts, products, departments, team, isRead, assignee |

Expand Down Expand Up @@ -88,6 +91,7 @@ List tickets from a Zoho Desk organization with optional filters. Returns a list
| ↳ `responseDueDate` | string | Response due date |
| ↳ `createdTime` | string | Created timestamp |
| ↳ `modifiedTime` | string | Last modified timestamp |
| ↳ `customerResponseTime` | string | Time the last customer response was received |
| ↳ `closedTime` | string | Closed timestamp |
| ↳ `resolution` | string | Resolution text |
| ↳ `threadCount` | string | Number of threads |
Expand Down Expand Up @@ -139,6 +143,7 @@ Retrieve a single Zoho Desk ticket by ID.
| ↳ `responseDueDate` | string | Response due date |
| ↳ `createdTime` | string | Created timestamp |
| ↳ `modifiedTime` | string | Last modified timestamp |
| ↳ `customerResponseTime` | string | Time the last customer response was received |
| ↳ `closedTime` | string | Closed timestamp |
| ↳ `resolution` | string | Resolution text |
| ↳ `threadCount` | string | Number of threads |
Expand Down Expand Up @@ -170,7 +175,7 @@ Update fields on an existing Zoho Desk ticket.
| `dueDate` | string | No | Due date \(ISO 8601\) |
| `description` | string | No | Ticket description |
| `resolution` | string | No | Resolution notes recorded on the ticket |
| `classification` | string | No | Ticket classification: Problem, Request, Question, or Others |
| `classification` | string | No | Ticket classification. Zoho\'s system-defined values are Problem, Request, and Question; portals can define custom values. Pass "" to clear it. |
| `customFields` | json | No | Custom field values as a JSON object, keyed by custom field API name |

#### Output
Expand Down Expand Up @@ -200,6 +205,7 @@ Update fields on an existing Zoho Desk ticket.
| ↳ `responseDueDate` | string | Response due date |
| ↳ `createdTime` | string | Created timestamp |
| ↳ `modifiedTime` | string | Last modified timestamp |
| ↳ `customerResponseTime` | string | Time the last customer response was received |
| ↳ `closedTime` | string | Closed timestamp |
| ↳ `resolution` | string | Resolution text |
| ↳ `threadCount` | string | Number of threads |
Expand All @@ -223,6 +229,7 @@ List comments on a Zoho Desk ticket.
| `ticketId` | string | Yes | Ticket ID |
| `from` | number | No | Pagination start index \(0-based\) |
| `limit` | number | No | Number of comments to return \(1-100, default 50\) |
| `sortBy` | string | No | Sort by commentedTime. Ascending by default; prefix with - for descending \(-commentedTime\). |

#### Output

Expand Down Expand Up @@ -307,6 +314,7 @@ List conversation threads on a Zoho Desk ticket, newest first (Zoho sorts by sen
| `ticketId` | string | Yes | Ticket ID |
| `from` | number | No | Pagination start index \(0-based\) |
| `limit` | number | No | Number of threads to return \(1-200, default 100\) |
| `sortBy` | string | No | Sort by sendDateTime. Zoho sorts descending \(newest first\) when unset; pass sendDateTime for oldest first. |

#### Output

Expand All @@ -333,7 +341,7 @@ List conversation threads on a Zoho Desk ticket, newest first (Zoho sorts by sen
| ↳ `isContentTruncated` | boolean | Whether Zoho truncated the thread content; fetch fullContentURL for the rest |
| ↳ `fullContentURL` | string | URL returning the untruncated thread content |
| ↳ `plainText` | string | Zoho's own plain-text rendering of the thread, when it supplies one |
| ↳ `status` | string | Delivery status of an outgoing thread \(SUCCESS/FAILED/DRAFT\) |
| ↳ `status` | string | Delivery status of the thread \(e.g. SUCCESS, PENDING, FAILED, DRAFT\) |
| ↳ `isDescriptionThread` | boolean | Whether this thread is the ticket's original description |
| ↳ `visibility` | string | Thread visibility \(e.g. public\) |
| ↳ `canReply` | boolean | Whether the thread can be replied to |
Expand Down Expand Up @@ -363,6 +371,7 @@ Retrieve the full content of a single Zoho Desk ticket thread.
| `orgId` | string | Yes | Zoho Desk organization ID |
| `ticketId` | string | Yes | Ticket ID |
| `threadId` | string | Yes | Thread ID |
| `include` | string | No | Related data to embed. Allowed: plainText — Zoho's own plain-text rendering of the thread |

#### Output

Expand All @@ -389,7 +398,7 @@ Retrieve the full content of a single Zoho Desk ticket thread.
| ↳ `isContentTruncated` | boolean | Whether Zoho truncated the thread content; fetch fullContentURL for the rest |
| ↳ `fullContentURL` | string | URL returning the untruncated thread content |
| ↳ `plainText` | string | Zoho's own plain-text rendering of the thread, when it supplies one |
| ↳ `status` | string | Delivery status of an outgoing thread \(SUCCESS/FAILED/DRAFT\) |
| ↳ `status` | string | Delivery status of the thread \(e.g. SUCCESS, PENDING, FAILED, DRAFT\) |
| ↳ `isDescriptionThread` | boolean | Whether this thread is the ticket's original description |
| ↳ `visibility` | string | Thread visibility \(e.g. public\) |
| ↳ `canReply` | boolean | Whether the thread can be replied to |
Expand Down Expand Up @@ -417,6 +426,7 @@ Retrieve a Zoho Desk contact by ID.
| `apiDomain` | string | No | Zoho Desk data-center REST base URL |
| `orgId` | string | Yes | Zoho Desk organization ID |
| `contactId` | string | Yes | Contact ID to retrieve |
| `include` | string | No | Comma-separated related data to embed. Allowed: accounts, owner |

#### Output

Expand Down
Loading
Loading