ZohoMail, a popular email service, utilizes OAuth 2.0 for secure third-party application access. While the ZohoMail OAuth flow is documented, navigating some nuances, like multi-region data centers and user/account information retrieval, can be tricky. This blog post aims to demystify ZohoMail’s OAuth flow, addressing the gaps in the official documentation.

Registering Your App and Obtaining Credentials

The first step, as with any OAuth flow, is registering your application on the Zoho API console. This grants you a Client ID and Client Secret, essential for authorization.

Initiating the Authorization Request

When your user interacts with your application and attempts to access ZohoMail data, your application initiates the authorization flow. You’ll send a request to Zoho’s authorization server, specifying:

  • Client ID: Your application’s unique identifier.
  • Redirect URI: The URL to which Zoho will redirect the user after authorization.
  • Scope(s): Permissions your application requests from the user (e.g., ZohoMail.IMAP).
curl -X GET -G https://accounts.zoho.com/oauth/v2/auth \
    -d client_id={ClientId} \
    -d response_type='code' \
    -d redirect_uri={redirectUri} \
    -d scope='ZohoMail.accounts.READ,ZohoMail.folders.CREATE' \
    -d state='CustomStateString' \
    -d access_type='offline' \
    -d prompt='consent'

Zoho will redirect the user to a login page, prompting them to log in to their Zoho account. Then, Zoho will present the user with a consent screen, outlining the requested permissions and asking for their authorization.

Authorization Code Grant

If the user grants consent, Zoho redirects them back to your application’s Redirect URI, along with an authorization code in the query string and location/domain name. This code is crucial for obtaining the access token. The location/domain parameter is not explained well in the ZohoMail documentation, but it’s described in the general Zoho OAuth documentation.


Before exchanging the code for an access token you need to construct a proper location/domain based server URL!

First, request server information:

GET https://accounts.zoho.com/oauth/serverinfo


    "result": "success",
    "locations": {
        "eu": "https://accounts.zoho.eu",
        "au": "https://accounts.zoho.com.au",
        "in": "https://accounts.zoho.in",
        "jp": "https://accounts.zoho.jp",
        "uk": "https://accounts.zoho.uk",
        "ca": "https://accounts.zohocloud.ca",
        "sa": "https://accounts.zoho.sa",
        "us": "https://accounts.zoho.com"

Next, use the location/domain to choose the right server.

Except, for the ZohoMail API you need to replace ‘accounts.’ with ‘mail.’, like in ‘https://mail.zoho.eu’!

Exchanging the Authorization Code for an Access Token

Now your application can send a POST request to ZohoMail’s token endpoint, including:

  • Grant type: Set to ‘authorization_code’
  • Client ID and Client Secret.
  • Redirect URI: The same URI used in the initial authorization request.
  • Authorization code: Received from Zoho in the previous step.
curl -X POST -G https://{locationUri}/oauth/v2/token \
    -d client_id={client_id} \
    -d client_secret={client_secret} \
    -d grant_type='authorization_code' \
    -d code={authorization_code} \
    -d redirect_uri={redirect_uri} \
    -d scope='ZohoMail.accounts.READ,ZohoMail.folders.CREATE'

Upon successful verification, Zoho responds with an access token and a refresh token. The access token allows your application to access ZohoMail data for a limited duration, while the refresh token can be used to obtain new access tokens when the original one expires.

  "access_token": "{access_token}", 
  "refresh_token": "{refresh_token}", 
  "api_domain": "https://www.zohoapis.com", 
  "token_type": "Bearer", 
  "expires_in": 3600

Here is how you can get the connected user information:

curl -X GET -H 'Authorization: Zoho-oauthtoken {access token}' \
    -G https://{locationUri}/oauth/user/info


    "First_Name": "John",
    "Last_Name": Smith,
    "Email": "jsmith@abc.com",
    "Display_Name": "jsmith",
    "ZUID": 123456

Accessing ZohoMail Data

With the access token, your application can make API calls to ZohoMail’s endpoints to manage emails, contacts, and other functionalities, as per the granted scopes.

curl -X GET -H 'Authorization: Zoho-oauthtoken {access token}' \
    -G https://{locationUri}/api/accounts

Refreshing the Access Token

A POST request to refresh a token should also be sent to the location based endpoint, including:

  • Grant type: Set to ‘refresh_token’
  • Client ID and Client Secret.
  • Redirect URI: The same URI used in the initial authorization request.
  • Refresh token: Received from Zoho during the initial authorization.
curl -X POST -G https://{locationUri}/oauth/v2/token \
    -d client_id={client_id} \
    -d client_secret={client_secret} \
    -d refresh_token={refresh_token} \
    -d grant_type='refresh_token' \
    -d &redirect_uri=https://zylker.com/oauth2callback


  "access_token": "{new_access_token}",
  "expires_in": 3600,
  "api_domain": "https://www.zohoapis.com",
  "token_type": "Bearer"


By understanding the intricacies of ZohoMail’s OAuth flow with multi-region support and account information retrieval, you can seamlessly integrate ZohoMail functionalities into your application. Remember to prioritize security practices like storing credentials securely and using HTTPS communication for data protection. This enhanced understanding empowers you to build robust and secure connections with ZohoMail, ultimately enriching your application’s capabilities.