Retrieving all domains in Zoho Desk requires first establishing a valid OAuth connection, then calling the organizations endpoint to discover your portal and org identifiers. Here is how our team at Beam Help — independent expert support for Zoho, not official Zoho support — recommends approaching this.
Why this matters
When you integrate with Zoho Desk programmatically, the API requires an org_id to scope almost every request correctly. Without it, calls to tickets, contacts, and other resources will fail or return unexpected results. Discovering your domains and org identifiers up front lets you store them and reuse them across all subsequent API calls. [1]
Step-by-step
Step 1. Ensure your OAuth application has the correct Desk scopes authorised. At minimum you need Desk.basic.READ, which covers organisations, agents, and departments. A full integration will also want scopes such as Desk.tickets.ALL, Desk.contacts.READ, and Desk.settings.READ depending on what you plan to do after domain discovery. [2]
Step 2. Obtain a valid access token for the user. If the token has expired, use the stored refreshtoken to call ZohoOAuth.refreshtokens(). Check that the response contains an access_token key before proceeding; if it does not, the refresh has failed and the user must reconnect. [1]
Step 3. Instantiate a ZohoDeskClient using the user's apidomain, the fresh accesstoken, and an empty string for org_id (since you have not discovered it yet). Wrap that client in a ZohoDeskApi instance. [5]
Step 4. Call api.getallorganizations(p={}) on the ZohoDeskApi instance. This is the primary endpoint for retrieving all organisations (domains) associated with the authenticated account. [5]
Step 5. Parse the response carefully — the shape can vary. If the result is a dict, look for a "data" key whose value is a list; the first element's "id" field is your org_id. If the result is already a list, take the first element's "id" directly. [1][5]
orgs = api.get_all_organizations(p={})
org_id = ""
if isinstance(orgs, dict):
items = orgs.get("data")
if isinstance(items, list) and items:
org_id = str(items[0].get("id", ""))
elif isinstance(orgs, list) and orgs:
org_id = str(orgs[0].get("id", ""))
Step 6. Once you have the orgid, persist it to your data store (for example, updating a deskorgid column in your connections table) so future requests do not need to repeat the discovery call. Set api.c.orgid on the live client instance as well so it is used immediately. [7]
Step 7. For portal/subdomain information, inspect the first organisation object for the fields urlName, subDomain, or portalName in that order of preference, falling back to id if none are present. Store the resolved value as desk_portal in your connections record. [6]
hc0 = orgs_list[0] # first org dict
portal = (
hc0.get("urlName")
or hc0.get("subDomain")
or hc0.get("portalName")
or hc0.get("id")
or ""
)
Step 8. Re-initialise ZohoDeskClient with the now-known org_id before making any further Desk API calls. All subsequent requests — tickets, contacts, departments — require this header to be present. [5]
Common pitfalls
- Empty
orgidon first call. The auto-discovery pattern exists precisely becauseorgidis not returned during the OAuth callback. Always callgetallorganizationsbefore assuming you have a valid org identifier. [1] - Response shape inconsistency. The organisations endpoint can return either a wrapped
{"data": [...]}dict or a bare list depending on the API version or region. Always handle both shapes in your parsing logic. [1][5] - Token expiry mid-flow. If
getallorganizationsraises an exception, check whether the access token has expired first. Pass atoken_refreshercallback intoZohoDeskClientso tokens are renewed transparently during long-running operations. [1] - Missing
Desk.basic.READscope. If the organisations call returns a permissions error, verify thatDesk.basic.READ(and ideallyDesk.basic.CREATE) are included in your authorised scopes. Without this scope the endpoint will be inaccessible. [2] apidomainregion mismatch. Theapidomainstored during OAuth (e.g.zohoapis.euvszohoapis.com) must match the data centre where the Desk account lives. Using the wrong domain will produce authentication or 404 errors. [3]
What to check
- Confirm that
orgidis non-empty and numeric after parsing thegetall_organizationsresponse, and that it has been written back to your connections store. [7] - Verify that
desk_portalresolves to a recognisable subdomain or URL name from the first organisation object, not just a raw numeric ID. [6] - Test a follow-up call (such as listing departments) using the discovered
org_idto confirm the value is accepted by Zoho Desk without a 403 or "Invalid orgId" error. [5]