Zoho Desk Integration
Connect Zoho Desk to TR-AI using OAuth2 client credentials.
Credentials required
| Field | Where to find it |
|---|---|
| Client ID | Zoho API Console → Your Server-based OAuth Client → Client ID |
| Client Secret | Zoho API Console → Your Server-based OAuth Client → Client Secret |
| Org ID | Zoho Desk → Setup → Developer Space → API → Org ID |
| Portal ID | Zoho Desk → Setup → Channels → Help Center → Portal name or ID |
Step 1 — Create a Server-based OAuth Client
- 1Open Zoho API ConsoleGo to https://api-console.zoho.com and click Add Client → Server-based Applications.
- 2Configure the clientSet any valid Redirect URI (e.g.
https://ticketresolve.ai/oauth/callback) — it is not used for client credentials flow. Click Create. - 3Note the credentialsCopy the Client ID and Client Secret.
Step 2 — Find your Org ID and Portal ID
- Org ID: Zoho Desk → Setup → Developer Space → API → Org ID (numeric).
- Portal ID: Zoho Desk → Setup → Channels → Help Center → your portal name or numeric ID.
Step 3 — Enter credentials in TR-AI
In your TR-AI Dashboard, open the Zoho Desk credentials card. Enter Client ID, Client Secret, Org ID, and Portal ID. Click Save. TR-AI exchanges credentials for a token and calls GET /api/v1/departments?limit=1 to verify access.
Step 4 — Configure the Zoho Desk webhook
- 1Open AutomationGo to Zoho Desk → Setup → Automation → Workflows → New Rule.
- 2Set the triggerModule = Tickets. Event = Ticket Created.
- 3Add a webhook actionAdd action: Webhook. Set Method =
POSTand URL:
https://ticketresolve.ai/api/integrations/zoho-desk/webhook/{your-trial-id}How TR-AI sends replies
TR-AI posts replies via POST /api/v1/tickets/{ticketId}/sendReply with channel: 'EMAIL'. This ensures the reply is emailed to the ticket requester — without channel: 'EMAIL', Zoho posts a web/portal reply only and no email is sent.
Reply content is wrapped in minimal HTML (<br> for newlines) since Zoho Desk renders the content field as HTML.
OAuth token caching
Tokens are cached per org and refreshed automatically on expiry. The cache key is {orgId}:{clientId[:16]}. Pass force=true to bypass the cache (used internally on 401 responses).
Token scope requested: Desk.tickets.ALL,Desk.contacts.READ.
Triage behaviour
When TR-AI cannot auto-resolve a ticket, it:
- Posts a public acknowledgement reply via
sendReplywithchannel: 'EMAIL'. - Assigns the ticket to a department named Triage if one exists — otherwise leaves it open and unassigned.
- Sets ticket status to
Openso agents see it. - Sends a Slack notification if configured.
Ticket status values
| Status | When TR-AI sets it |
|---|---|
| Open | Triage path — ticket needs human attention |
| Closed | Auto-resolved — reply posted successfully |