Listing domains in Zoho Desk via the API involves discovering your portal's identifier and org ID so that every subsequent request is correctly scoped to your account. Here at Beam Help — independent expert support for Zoho, not official Zoho support — we walk you through exactly how that discovery process works.
Why this matters
When you connect to Zoho Desk programmatically, the API needs to know which portal (domain) and organisation you are targeting before it can return or modify records. Without the correct portal name and org ID, links to tickets, contacts, and accounts will not resolve properly. This is especially important in multi-tenant setups where a single OAuth connection may need to serve several portals. Getting this right up front prevents broken deep-links and misdirected API calls.
Step-by-step
Step 1. Ensure your OAuth token includes the right scopes before making any domain-listing call. The minimum required scope for reading organisational and portal data is Desk.basic.READ. A full integration will also want Desk.tickets.READ, Desk.contacts.READ, and similar module-level scopes added to the same token request. [5]
Step 2. After completing the OAuth flow, inspect the token response for the api_domain field. This field tells you which Zoho data-centre (e.g. com, eu, in, au, jp) your account lives on. Parse the suffix after zohoapis. to determine the correct data-centre code (dc). Storing this value is essential because every Desk URL is built from it — for example, the agent portal base for the com data-centre is https://desk.zoho.com/agent. [2] [3]
Step 3. Call the Zoho Desk organisations endpoint using your freshly issued access token. The response returns a list of organisation objects. Extract the id field from the first item in that list — this becomes your deskorgid. Persist it against your connection record so you do not need to re-discover it on every request. [4]
Step 4. In the same API call (or a dedicated portals/helpcentres call), look for the portal identifier. The fields to check, in priority order, are urlName, subDomain, portalName, and finally id. Take the first non-empty value — this becomes your desk_portal slug. Store it alongside the org ID. [6]
Step 5. Construct your base Desk URL by combining the data-centre code and the portal slug:
https://desk.zoho.{dc}/agent/{portal}
For record-level links (tickets, contacts, accounts), append the module path after the portal segment. For example, a ticket detail URL follows the pattern:
https://desk.zoho.{dc}/agent/{portal}/tickets/details/{TicketId}
If no portal slug was discovered, fall back to using the numeric deskorgid in the same position. [3]
Step 6. Verify the assembled links by navigating to the fallback URLs for each entity type. If the portal slug is missing, the system should still be able to open the general tickets list at {deskrecordsroot}/tickets, the contacts list at {deskrecordsroot}/contacts, or the accounts list at {deskrecordsroot}/accounts. [1]
Common pitfalls
- Scope gaps. Forgetting
Desk.basic.READin your OAuth scope list means the organisations/portals endpoint will return an authorisation error. Double-check that bothDesk.basic.READandDesk.basic.CREATEare present if you also need to write basic settings. [5] - Wrong data-centre. If you hard-code
combut the account is oneuorin, all constructed URLs will be unreachable. Always derivedcdynamically from theapi_domainreturned during OAuth. [2] - Stale portal slug. Portal
urlNamevalues can change if an admin renames the help centre. If links start returning 404s, re-run the discovery step to refresh the storeddesk_portalvalue. [6] - Multi-item org lists. The discovery logic takes
items[0]from the response. In accounts with multiple organisations, you may need to let the user select the correct org rather than defaulting to the first. [4]
What to check
- Confirm that your stored
dcvalue matches the suffix in theapi_domainfield returned by Zoho during OAuth (e.g.zohoapis.eu→dc = eu). [2] - Verify that both
deskorgidanddesk_portalare populated in your connection record before constructing any deep-links to Desk records. [3] [6] - Test at least one ticket URL in the format
https://desk.zoho.{dc}/agent/{portal}/tickets/details/{TicketId}to confirm end-to-end resolution. [3]