A year or two ago I did some work for a client with the Zoho API version 1.0. Now, they’ve deprecated that API version and will stop supporting it soon, so I must upgrade to version 2 of the API.

Version 2.0 of the Zoho API uses OAuth for authentication which is not something I have used often, if ever. The API’s I’ve worked with in the past may have had an OAuth option, but usually, there was another option available if using the API for ourselves with our own account. In other words, I am not writing a plugin to be used by multiple clients with different login information. This is custom code for one client to be used to integrate their website with their zoho account.

I had a hard time getting the authentication to work, so I thought I would write about what I found to work in the end. Hopefully, this will save someone else some time.

I decided to use the PHP SDK to take advantage of the persistence handler

I was going to use the PHP SDK at first, but I don’t have a lot of work to do with this API. I just need to insert a couple of leads and vendors and pull some emails from their current contacts, so learning the SDK when seemed like overkill. I am usually pretty good at learning API’s using JSON or XML.

However, once I finally figured out how to do OAuth using the API without the SDK, I realized that I would have to write a lot of code to handle the persistence of the grant, access and refresh tokens. I decided to use the PHP SDK just to take advantage of their persistence handler.

I decided to use the file handler instead of a database for persistence

Since I don’t have a lot of users and I didn’t want to set up another database for my clients site, the file seems to be our best option. The database seemed like overkill just to handle the access and refresh tokens.

To make this work correctly, I had to create a persistence file named zcrm_oauthtokens.txt and leave it empty (it’s important that it’s named exactly that). I could not get it to work until I created this empty file.

Setting up the configuration file

There are two configuration files in the SDK. The first is configuration.properties.

I first set the sandbox to true, but this didn’t work well for me. Not sure why, but the code only worked when setting this to false.

I created the application log file by creating a ZCRMClientLibrary.log and then putting the path to that file in the configuration file. I haven’t gotten anything to show up in this file yet, but I’ll update this post when and if I do. Maybe I have this setup incorrectly?

You need to set the currentUserEmail to the email address of the user email of the Zoho account that’s used for creating the grant token.

My configuration file looks like this:


The other configuration file is the oauth_configuration.properties file in the same location as the first configuration file. These are in the vendor/zohocrm/php-sdk/src/resources folder.

The oauth_configuration file needs to have the client_id and the client_secret from the zoho developer console where you set up the app. This is documented fairly well in the zoho api documentation.

The redirect_uri in the configuration file should match the redirect_uri used on the developer console app setup as well and should be the name of the script that will be making the api calls.

The token_persistence_path should be the path to the new file you created without the file name – just the path.

The access_type should be offline and the persistance_handler_class should be ZohoOAuthPersistenceHandler.

My file looks something like this:


Getting my Access and Refresh Tokens

The Access and Refresh tokens only need to be gotten once per user and since I’m the only user, then I only have to do this once to add the tokens to the zcrm_oauthtokens.txt file.

Here is the code I used to get these tokens:

	$oAuthClient = ZohoOAuth::getClientInstance();
	$grantToken = "{grant token goes here}";
	$oAuthTokens = $oAuthClient->generateAccessToken($grantToken);

The grant token can be gotten by either using the self-client in the developer console or going to the specific url listed in the documentation. Take note that the grant token will only last for 3 to 10 minutes depending on what you select when you use one of these methods. So, once you’ve got the grant token, you must insert it into your code and run the code to create the zcrm_oauthtokens.txt file within that small time frame. If you miss the time frame, you may have to delete the contents of that file (if there are any) and start over. This will not work if there is information already in that file, it will give an error. Or at least, that was my experience.

To use the self-client or the url, you will need to know the scope of access that you will need. For my testing, I wanted to give myself permission to everything. I used the self-client to produce my grant token. Through trial and error I finally figured out that I should have the scope set to this:


Notice that there are NO spaces in that line. When I put spaces after the commas, nothing happened when I clicked the button.

I set the self-client to the scope above and then gave myself 10 minutes, just in case things didn’t go as expected. Make sure the zcrm_oathtokens.txt file is empty, but there. then run the script. For me, nothing happened. I got a blank screen, however, the very first time, it took me to a zoho web page that asked me to accept the access to my account. Every time after that, I only got a blank screen. I’m sure that’s because I didn’t have any code yet in my script where the redirect_url was returning the call.

Once the script had finished, I looked at my zcrm_oathtokens.txt file and saw a serialized array that did, indeed, have my tokens in there along with my email address. Success!

Next I ran the sample code from one of the version 2.0 API examples and got the expected results!

    foreach ($moduleArr as $module) {
        echo "ModuleName:".$module->getModuleName();
        echo "SingLabel:".$module->getSingularLabel();
        echo "PluLabel:".$module->getPluralLabel();
        echo "BusinesscardLimit:".$module->getBusinessCardFieldLimit();
        echo "ApiName:".$module->getAPIName();
        if($fields==null) {
        foreach ($fields as $field) {
            echo $field->getApiName().", ";
            echo $field->getLength().", ";
            echo $field->IsVisible().", ";
            echo $field->getFieldLabel().", ";
            echo $field->getCreatedSource().", ";
            echo $field->isMandatory().", ";
            echo $field->getSequenceNumber().", ";
            echo $field->isReadOnly().", ";
            echo $field->getDataType().", ";
            echo $field->getId().", ";
            echo $field->isCustomField().", ";
           echo $field->isBusinessCardSupported().", ";
          echo $field->getDefaultValue().", ";
} catch (ZCRMException $e) {
    echo $e->getCode();
    echo $e->getMessage();
    echo $e->getExceptionCode();

I would love to hear about your experience with the API in the comments below. If you need help with the API, please contact me.

Leave a Comment

Your email address will not be published. Required fields are marked *