Beam Help
Get help now

How-to · Zoho CRM

How to get users in Zoho

Retrieve a list of all users in your Zoho account.

Retrieving users in Zoho CRM via OAuth requires a valid access token and a call to the Zoho Accounts user-info endpoint — here is exactly how that flow works, from credential setup through to parsing the response.


Why this matters


When building integrations or internal tools on top of Zoho CRM, you often need to identify *who* is authenticated — their user ID, email address, and organisation details — before making any CRM API calls. Getting this wrong leads to 401 errors, mismatched org IDs, and broken multi-tenant logic. Understanding the full OAuth callback and user-info retrieval flow saves significant debugging time.


> Beam Help is independent expert support for Zoho — we are not official Zoho support.


---


Step-by-step


Step 1. Register your application in the Zoho API Console and collect the credentials you need. Navigate to the API Console, create a Server-based Application, set your redirect URI (e.g. http://localhost:8080/api/auth_callback), and record your Client ID and Client Secret. When selecting OAuth scopes, include at minimum ZohoCRM.users.ALL, ZohoCRM.modules.ALL, and ZohoCRM.settings.ALL. [7]


Step 2. Configure your environment. Create a .env file at the project root and populate it with ZOHOCLIENTID, ZOHOCLIENTSECRET, and optionally ZOHO_DC (accepted values: com, eu, in, com.au, jp — defaults to com). The data-centre value controls which regional endpoint is called in subsequent steps. [7]


Step 3. Handle the OAuth callback in your server. When Zoho redirects back to your callback route, extract the code parameter from the query string. Pass that code to your OAuth handler (ZohoOAuth.handleoauthcallback(code)), which exchanges it for an access token and a refresh token. If the response does not contain an access_token key, surface the error immediately rather than proceeding. [6]


Step 4. Call the Zoho Accounts user-info endpoint to retrieve the authenticated user's details. Construct the URL as:


https://accounts.zoho.<DC>/oauth/user/info

Send a GET request with an Authorization: Bearer &lt;access_token&gt; header. The JSON response contains the fields you need to identify the user. [1]


Step 5. Parse the response carefully — field names vary by data centre. Extract the user ID from ZUID, and the email from Email. For the organisation ID, try orgid first, then organizationid, then ZGID; if none are present (single-user orgs), fall back to the ZUID value itself. For the organisation name, check companyname, then organizationname, then Company_Name; if all are absent, derive a fallback from the domain portion of the email address. [1]


Step 6. Persist the user and organisation. Use the zohouserid to look up an existing user record; create one if it does not exist. Separately, call getorcreateorganization with the zohoorgid and orgname values, then link the user to that organisation via updateuserorg. Store the orgid in the session alongside userid to support multi-tenant scenarios. [6]


Step 7. Store the connection tokens. Save the accesstoken, refreshtoken, apidomain, tokenexpiresat, and dc into your zohoconnections table, keyed by user_id. If a connection record already exists for that user, update it; otherwise insert a new row. [8]


Step 8. On subsequent requests, retrieve the stored connection and proactively refresh the access token if it is within 120 seconds of expiry. After a successful refresh, update both accesstoken and tokenexpires_at in the database before proceeding with any Zoho CRM API call. [2]


Step 9. To check the currently authenticated user's status at any time, query your users table by session[&quot;userid&quot;] and your zohoconnections table by user_id. Return connected: true only when a connection row exists, along with the stored email address. [4]


---


Common pitfalls


  • Wrong data centre. If ZOHODC is set to com but your users are on the EU or IN data centre, the user-info URL will return an error or an empty response. Always derive the DC from the apidomain returned in the OAuth callback (look for the segment after zohoapis.) and persist it. [8]
  • Missing org ID fields. The organisation ID field name is not consistent across Zoho data centres. Failing to try all three variants (orgid, organizationid, ZGID) before falling back will cause org-creation logic to silently use the wrong identifier. [1]
  • Token expiry mid-request. Access tokens expire after approximately 3600 seconds. Without proactive refresh (the 120-second skew buffer), long-running operations will hit 401 errors partway through. [2]
  • Single-user org edge case. For accounts without a formal organisation, none of the org ID fields may be populated. The safe fallback is to use the ZUID as the org identifier so that downstream org-creation logic does not fail. [1]

---


What to check


  • Scopes are correct: Confirm that ZohoCRM.users.ALL is included in your registered application's scope list; missing scopes silently restrict what the user-info endpoint returns. [7]
  • DC is persisted accurately: After the OAuth callback, verify that the dc column in zoho_connections matches the actual regional domain of the authenticated user's Zoho account. [8]
  • Token refresh is working: After storing a connection, simulate a near-expiry scenario and confirm that getzohoconnection returns a valid, refreshed access_token rather than an expired one. [2]

Sources cited

  1. [1] zoho_oauth.py
  2. [2] server.py: get_zoho_connection
  3. [3] server.py: get_zoho_api
  4. [4] server.py: me
  5. [5] db.py
  6. [6] server.py: auth_callback
  7. [7] README.md
Get Users in Zoho | Beam Help — Beam Help