Hello and welcome to another Kaizen week!
In this week's post, we'll show you how to get started with Zoho CRM's PHP SDK, and walk you through the configuration and initialization process.
PHP Software Development Kit
PHP SDK allows you to create client PHP applications that can be integrated with Zoho CRM effortlessly. It serves as a wrapper for the
REST APIs, thus making it easier to use the services of Zoho CRM.
Why PHP SDK?
Easy authentication: You don't have to worry about manually managing authentication because the PHP SDK takes care of generating access/refresh tokens for you.
Easy and Efficient data exchange: With the PHP SDK, you can easily exchange data between Zoho CRM and your client PHP application, where the CRM entities are modelled as classes. You can declare and define CRM API equivalents as simple functions in your PHP application.
Prerequisites
- The client app must have PHP 7 or above with a cURL extension. cURL extension is used to connect and communicate with the Zoho CRM APIs.
- The client app must have the PHP SDK installed through Composer.
How to start using the PHP SDK?
- Prerequisite : Register your application with Zoho CRM.
- Install the PHP SDK.
- Knowledge Base : Token Persistence
- Configuration
- initialization.
1. Register your application with Zoho CRM
Registering your application with Zoho CRM is a mandatory step in order to authenticate and authorize API calls using the OAuth2.0 standards.
- Go to https://api-console.zoho.com
- Click on Get Started or +ADD CLIENT.
- Choose the Client Type.
- Fill in the necessary details and click CREATE. Once you successfully register your self-client, you will receive a Client ID and Client Secret.

2. Install PHP SDK
1. Install Composer, if not already installed. Please check the corresponding link for installation instructions.
2. Install PHP-SDK using Composer
3. To use the SDK in your project, add the following line in your project PHP files. This loads and includes our PHP-SDK library in your project. If you skip this step, you will get a fatal error in response due to the missing libraries.
require 'vendor/autoload.php'; |
3. Token Persistence
Token persistence refers to storing and utilizing authentication tokens provided by Zoho, enabling the SDK to refresh the access tokens without the need for user intervention. The SDK offers three types of persistence - File, DB, and Custom - with file persistence being the default method.
The persistence is achieved by writing an implementation of the inbuilt TokenStore interface, which has the following callback methods.
Method | Description |
getToken($user, $token) | Invoked before firing a request to fetch the saved tokens. This method returns an implementation of Token interface object for the library to process it. |
saveToken($user, $token) | Invoked after fetching access and refresh tokens from Zoho. This method saves the token details. |
deleteToken($token) | This method is used to delete the given token details. |
getTokens() | This method is used to retrieve all the stored tokens. |
deleteTokens() | The method to delete all the stored tokens. |
getTokenById($id, $token) | This method is used to retrieve the user token details based on the unique ID. |
a. Token Persistence using a Database
Database persistence is a technique that involves storing and retrieving data from a database. If you prefer using database persistence, you can use MySQL.
Create a table in your database with the required columns. For example, if you want to persist your tokens in a table named token in database named zoho, use the following:
CREATE DATABASE zoho; // use this to create database named zoho // use this to create a table named token, with the necessary columns CREATE TABLE token ( id varchar(255) NOT NULL, user_mail varchar(255) NOT NULL, client_id varchar(255), client_secret varchar(255), refresh_token varchar(255), access_token varchar(255), grant_token varchar(255), expiry_time varchar(20), redirect_url varchar(255), primary key (id) ); |
In this example, your tokens will be persisted in the token table in your zoho database.
b. File Persistence
File Persistence allows storing and retrieving the authentication tokens from the given file path. The file contains
id, user_mail, client_id, client_secret, refresh_token, access_token, grant_token, expiry_time and
redirect_url. c. Custom Persistence
Custom Persistence refers to a technique where users can create their own method of storing and retrieving authentication tokens. To use this method, users need to implement the TokenStore interface and override its methods according to their own logic.
4. Configuration
Configuration is a critical step in which you set up SDK's configuration details like user authentication, token persistence, logging and API call timeout settings, and more. Listed below are the keys that you define in this step.
Key | Description |
| Represents the mail id, which is used to identify and fetch tokens from the File or DB. |
| Represents the data centre details in Domain::Environment pattern. Domains : USDataCenter, EUDataCenter, INDataCenter, CNDataCenter, AUDataCenter Environments : PRODUCTION(), DEVELOPER(), SANDBOX() |
| Contains user token details. Depending on the tokens, you can choose grantToken flow, refreshToken flow or accessToken flow. |
| Contains the configuration for logging exceptions and API call information. By default, the logs will be available in the workspace as sdk_logs.log. |
| Contains details for the Token Persistence object. You can choose between DB Store, File Store or Custom Store, and configure accordingly. |
| Contains additional configuration details like timeout, autorefresh fields, picklistvalidation, etc |
| Contains the details of the proxy, if you are using a proxy server to authenticate and make the API calls. |
| The path containing the absolute directory path to store user specific files containing the module fields information. |
Let us discuss how to configure each of them, in detail.
a. user : The user key will be used to store and identify the tokenstore details in the DB or File Storage for token persistence. Create an instance of UserSignature that identifies the current user with the following :
b. environment : The API environment which decides the domain and the URL to make API calls.
- $environment = USDataCenter::PRODUCTION();
c. token : Create an instance of OAuthToken with the information that you get after registering your Zoho client. Depending on the tokens available with you, you can choose one of the following flows.
Note : You need to generate the tokens (grant/access/refresh) beforehand.
d. logger : Create an instance of Logger Class to log exception and API information. You can set the level you want to log (FATAL, ERROR, WARNING, INFO, DEBUG, TRACE, ALL, OFF), and also configure the file path and file name for the log file.
$logger = (new LogBuilder()) ->level(Levels::INFO) ->filePath("/Documents/php_sdk_log.log") ->build(); |
e. store : Configure your token persistence using this method. If this is skipped, the SDK creates the sdk_tokens.txt in the current working directory to persist the tokens by default.
Custom Store - In this method, you can implement your own method for storing and retrieving the tokens. Please note that to do so, you must implement the TokenStore interface, and override its callback methods (getToken, saveToken, deleteToken, getTokens, deleteTokens, getTokenById).
$tokenstore = new CustomStore(); |
Note : The corresponding storage will have id, user_mail, client_id, client_secret, refresh_token, access_token, grant_token, expiry_time and redirect_url. The id is a unique system generated key.
f. SDKConfig : The additional SDK configurations are taken care of with this method.
Configuration Key | Description |
autoRefreshFields Default Value : False | A boolean configuration key to enable or disable automatic refreshing of module fields in the background. If set to true, fields are refreshed every hour, and if set to false, fields must be manually refreshed or deleted. |
pickListValidation Default Value : True | This field enables or disables pick list validation. If enabled, user input for pick list fields is validated, and if the value does not exist in the pick list, the SDK throws an error. If disabled, the input is not validated and the API call is made. |
enableSSLVerification Default Value : True | A boolean field to enable or disable curl certificate verification. If set to true, the SDK verifies the authenticity of certificate. If set to false, the SDK skips the verification. |
connectionTimeout Default Value : 0 | The maximum time (in seconds) to wait while trying to connect. Use 0 to wait indefinitely. |
| The maximum time (in seconds) to allow cURL functions to execute. Use 0 to wait indefinitely. |
- $autoRefreshFields = false;
- $pickListValidation = false;
- $enableSSLVerification = true;
- $connectionTimeout = 2;
- $timeout = 2;
- $sdkConfig = (new SDKConfigBuilder())
- ->autoRefreshFields($autoRefreshFields)
- ->pickListValidation($pickListValidation)
- ->sslVerification($enableSSLVerification)
- ->connectionTimeout($connectionTimeout)
- ->timeout($timeout)
- ->build();
g. requestProxy : Create an instance of RequestProxy containing the proxy properties of the user. Configure this only if you're using a proxy server to make the API calls.
$requestProxy = (new ProxyBuilder()) ->host("proxyHost") ->port("proxyPort") ->user("proxyUser") ->password("password") ->build(); |
h. resourcePath : Configure path containing the absolute directory path to store user specific files containing module fields information.
$resourcePath = "/Documents/phpsdk-application"; |
5. Initilization
Once you have completed the configuration process, you can move on to initializing the SDK and begin making API requests.
Here is a sample code to initialize the SDK, using refresh token flow and DB Persistence.
<?php use com\zoho\api\authenticator\OAuthBuilder; use com\zoho\api\authenticator\store\DBBuilder; use com\zoho\api\authenticator\store\FileStore; use com\zoho\crm\api\InitializeBuilder; use com\zoho\crm\api\UserSignature; use com\zoho\crm\api\dc\USDataCenter; use com\zoho\api\logger\LogBuilder; use com\zoho\api\logger\Levels; use com\zoho\crm\api\SDKConfigBuilder; use com\zoho\crm\api\ProxyBuilder; use com\zoho\api\authenticator\store\DBBuilder;
require_once "vendor/autoload.php";
class Initialize { public static function initialize() { $environment = USDataCenter::PRODUCTION(); $token = (new OAuthBuilder()) ->clientId("1000.xxxxxxxxxxxxxxxx") ->clientSecret("554a9776d10ff016a92c1eb01xxxxxxxxxx") ->refreshToken("1000.xxxxxxxxxxxxxxxxxxxx") ->build(); $logger = (new LogBuilder()) ->level(Levels::INFO) ->filePath("/Documents/php_sdk_log.log") ->build(); $tokenstore = (new DBBuilder()) ->host("insert_your_hostname_here") ->databaseName("insert_your_database_name_here") ->userName("insert_your_db_username_here") ->password("insert_your_db_password_here") ->portNumber("insert_your_portnumber_here") ->tableName("insert_your_table_name_here") ->build(); $autoRefreshFields = false; $pickListValidation = false; $connectionTimeout = 2; $timeout = 2; $sdkConfig = (new SDKConfigBuilder()) ->autoRefreshFields($autoRefreshFields) ->pickListValidation($pickListValidation) ->sslVerification($enableSSLVerification) ->connectionTimeout($connectionTimeout) ->timeout($timeout) ->build(); $resourcePath = "/Documents/phpsdk-application"; $requestProxy = (new ProxyBuilder()) ->host("proxyHost") ->port("proxyPort") ->user("proxyUser") ->password("password") ->build(); (new InitializeBuilder()) ->user($user) ->environment($environment) ->token($token) ->store($tokenstore) ->SDKConfig($configInstance) ->resourcePath($resourcePath) ->logger($logger) ->requestProxy($requestProxy) ->initialize(); } } ?> |
You are now all set to explore the functionalities of SDK. Here is a sample code to get the records from Leads module, with the ifmodifiedsince header.
<?php use com\zoho\api\authenticator\OAuthBuilder; use com\zoho\crm\api\dc\USDataCenter; use com\zoho\crm\api\InitializeBuilder; use com\zoho\crm\api\UserSignature; use com\zoho\crm\api\record\RecordOperations; use com\zoho\crm\api\record\GetRecordsHeader; use com\zoho\crm\api\HeaderMap; use com\zoho\crm\api\ParameterMap; require_once "vendor/autoload.php";
class Record { public static function initialize() { $environment = USDataCenter::PRODUCTION(); $token = (new OAuthBuilder()) ->clientId("1000.xxxxxxx") ->clientSecret("4b5baxxxxxxxxxxxxf") ->grantToken("1000.xxxxx") ->build(); (new InitializeBuilder()) ->user($user) ->environment($environment) ->token($token) ->initialize(); }
public static function getRecords() { $recordOperations = new RecordOperations(); $paramInstance = new ParameterMap(); $headerInstance = new HeaderMap(); $ifmodifiedsince = date_create("2022-06-01T12:00:00+05:30")->setTimezone(new \DateTimeZone(date_default_timezone_get())); $headerInstance->add(GetRecordsHeader::IfModifiedSince(), $ifmodifiedsince); $response = $recordOperations->getRecords("Leads", $paramInstance, $headerInstance); echo($response->getStatusCode() . "\n"); print_r($response); } } Record::initialize(); Record::getRecords(); |
Next week, we will dive deeper and provide more sample codes to help you further. Stay tuned!
If you have any queries, let us know the comments below, or drop an email to
support@zohocrm.com. We would love to hear from you.

Recent Topics
Zoho Survey Goes to Junk Folder
Hello, My company is wanting to use Zoho Survey to send out a customer satisfaction survey, and we were wondering if Zoho Campaigns allows the emails to not go into their junk folder. We sent out a test email campaign to our team and for some people it went to their inbox and for others it went to their junk folder. Is there a way to eliminate this from happening? Hope to hear from you soon! Thanks!
Nifty enhancements to Reports in Zoho CRM
Dear Customers, We hope you’re well! We are here with a line of useful enhancements to Reports in Zoho CRM that are readily available to access. Include or exclude Record ID in the report export Display currency fields in record currency Capture report
need a formula to return value as shown (zoho sheet)
Dear folks, What should be the formula in cell B3 to get that output, based on input sheet data.
need a formula to return value as shown (zoho sheet)
Hello folks, what should be the formula in B3, to get the value shown based on input sheet ranges. thanks in advance.
Playground: An exclusive test environment to analyze Field Prediction accuracy
Hello everyone, We are introducing Playground: an exclusive proactive testing environment for businesses to analyze Zia's prediction accuracy. This allows admins and agents to: Run predictions on actual tickets or specific content for realistic test conditions.
Attention: Upcoming changes to Zoho Assist support for older windows versions
At Zoho Assist, our goal is to provide you with secure, reliable, and feature-rich remote support experiences. To maintain this standard, we periodically align our platform with the latest technology and security updates from the broader software ecosystem.
Send again email with link for signup
Hello, I have a lot of problem to send contract my email, also missing the features "share link". How can I send again email to client and me wit link for signup a contract? Everytime it's a disaster!
How do I synchronize a quote to an opportunity?
Hi everyone, We don't quote anything via Zoho but we use it to track services/products so that I can see what was actually sold, vs an opportunity with just shows an amount. We use the quotes for other purposes, mostly to request a quote from Salesforce but we don't invoice or do sales orders or anything. (Basically a user makes a quick quote in Zoho, adds items and pricing, and then exports to PDF which gets emailed to our Quote Desk who then enters the request into Salesforce). Just wondering
Zoho Sprints Android app update: Tags and Epic search
Hello everyone! We are excited to introduce tags and an option to search items within Epic module on the latest Android version(v2.0.2) of the Zoho Sprints mobile app. Let's take a look at these features: Tags You can now create, edit, and delete tags,
Zoho CRM Webhooks - Dynamic URL
Hi Zoho, We've noted a gap in the webhooks function that if improved would increase use cases significantly. The "URL to Notify" field in "Create a Webhook" only supports static information. We have a number of use cases where we could use webhooks more
Work Order Creation Issue
Dear Team, I would like to inquire about the daily limit for Work Order creation in Zoho FSM. Yesterday (02/05/2025) at around 6:30 PM GST, I attempted to create a Work Order, but I have been unable to do so since then. Please find the attached image
Tracking on Zoho Booking
Hi We want to use Zoho Booking for our appointment management. We're using Calendly as of now that lets us track sources of the appointments made including UTM parameters. Is there a way for us to do same with Zoho Bookings?
Pre-created Popular Zoho Flows returns with 404 Error
Your popular Zoho Flows are returning with a 404 page error. This applies to all work flows in your Gallery Space. See video here for further clarification. When will this be fixed? https://drive.google.com/drive/folders/1kDl4ni5EQeLHWeaoIDdtRqoUbW8FNLfO?usp=sharing
CRM Feature Request
When enabling Translation in Zoho CRM I would like to see the ability to remove the language "English (US)". I have encountered a user experience issue with a client recently. The client uses English (UK) but they are based in Spain, so they have activated
Import your Google Docs Spreadsheets into Zoho Sheet
You can now import your Google spreadsheet into Zoho Sheet. This will be useful if you want to switch to Zoho Sheet or if you want to simply try out Zoho Sheet. If you don't have an account with Zoho, you can still try this by signing in with your Google account. Here is a video on how to do this. Note: Existing charts won't appear in spreadsheets you import from Google Docs as the Export functionality of Google Docs doesn't give out the charts. Check out the announcement in our blog: https://blogs.zoho.com/general/import-google-docs-into-zoho-productivity-suite
Support Mixed Visibility Settings in Knowledge Base Categories
Hello Zoho Desk Team, We hope you're all doing well. We’d like to submit a feature request regarding visibility settings in the Knowledge Base module. 🎯 Current Limitation As of today, when a category is set to a specific visibility level (e.g., Public),
Will a campaign send duplicates is same email is on two separate lists
Hi I have two lists to which I want to send campaign. One list is ALL leads and other is list of opportunities and current students. There is overlap between the two lists My question is if I send one campaign to all, will zoho automatically know only to send the email once to the duplicate email?
Time Based Report / Dashboard
We measure our support agent's KPI based on their response time and resolution time from the time the ticket is assigned to them The time based dashboard should provide this information however there is a problem with us referring to this dashboard We
Zoho Learn API Access?
We love using Zoho Learn to manage our internal trainings and knowledge base. What we'd really love is to be able to query Learn via API so that in Zoho Projects, Zoho Creator, or Zoho Desk, we can recommend relevant Learn articles and manuals to team
creating buttons in zoho site
the connection between zoho site and zoho learn will be awesome and amazing feature so the user instead of registering himself twice just one time register on zoho site will be enough and creating accout on zoho learn instead of registering on zoho learn
Two Problems with the Description Field
Our ticket workflow is often like this. Client calls or emails (to a personal email address) reporting a problem. We create a ticket and enter a description. Problems: 1. By my way of thinking when we enter a description, that is an internal comment (unless we mark it public). Yet it seems there is no way to mark it internal, and Desk just starts inserting it into communications. 2. Additionally, in the conversation view it makes it appear it was emailed by the customer and inserts their name on
Lookup Field limitations
Good day all, Is anyone else frustrated with the lookup field limitation? I have an enterprise license, but I only get 10 lookups. Additionally, the custom module has been available for a while and is still in diapers. If you want good reporting, you
Automation#36: Auto-create time-entry after performing the Blueprint transition
Hello Everyone, This week’s edition focuses on configuring a custom function within Zoho Desk to streamline time tracking within the Blueprint. In this case, we create a custom field, and request the agent to enter the spending time within the single
Dynamically Sync zoho.adminuserid with Current App Admin
Hello Zoho Team, We hope you're doing well. We’d like to request an important enhancement to the Deluge sendmail task functionality. As per the current behavior, in most Zoho services (excluding Zoho Cliq, Zoho Connect, Zoho Mail, and Zoho Sheet), the
"Improper Statement" Error on Deluge Loops (while/for) when Processing a Date Range
Hello, Zoho Community, I'm facing a very specific issue with a Deluge script and would appreciate any insights from the community. The Goal: I have a form (ausencia_visitadoras) where a user inputs a start date and an end date for a period of absence.
Zoho Meeting iOS app update: Hearing aid, bluetooth car audio and AirPlay audio support.
Hello everyone! We are excited to announce the below new features in the latest iOS update(v1.7.4) of the Zoho Meeting app: 1. Hearing aid support: Hearing aid support has been integrated into the application. 2. Bluetooth car Audio, AirPlay audio support:
Automating Daily Lottery Result Publishing with Zoho Creator or Flow – Any Best Practices?
Hello Zoho Community, I run a results-based informational website in Brazil called CaminhoDaSorte.com, where we publish daily Jogo do Bicho results. Right now, we're doing this process manually every day — but we’re looking to automate the backend using
issues with manually shipping sales orders - advise needed please
we are new to zoho inventory. we are going to roll the program out to our company within a couple of weeks and during the implementation process we have come into a roadblock with manually packaging and shipping sales orders. its important to note important
I do not see the “Lead Forms” option under Integrations
Hi, I’m using Zoho Social on a Premium plan. I’ve connected LinkedIn Company Page and have a valid LinkedIn Ad Account with Lead Gen Forms. However, I do not see the “Lead Forms” option under Integrations, so I can’t enable LinkedIn Lead Generation. Please
STOCK function showing #N/A! even thought the Stock symbol is valid
Zoho Team, I use STOCK function on Zoho Sheet to fetch the recent Last Closing Price. Some stock symbols are valid but when the STOCK function is applied, it shows #N/A! Attaching an image for reference.
What’s the Correct Integration Flow Between Zoho Inventory, ShipStation, and Multi-Channel Sales Platforms?
Hi Zoho Community, I’m currently implementing Zoho One to manage all of my business processes, and I’d appreciate some guidance on the correct integration flow for the tools I’m using. Here’s my current setup: Zoho Inventory is my central system for managing
Beyond Email: #4 Note taking done right with Notes
With her favorite links now saved in Bookmarks, Sarah is feeling even more at home in Zoho Mail. As her day fills up with meetings and project discussions, she often finds herself scribbling quick ideas and reminders—only to lose track of them later.
When will Sales Order and Invoice Synchronisation with Zoho CRM be Available?
When will Sales Orders and Invoices, created in Zoho Books or Inventory be made available in Zoho CRM? John Legg Owner: The Debug Store
Generate Unique Customer ID for Each for All Contacts
Generate Unique Customer ID for Each for All Contacts
Bookings to Books automation using Flow
I'm using Zoho Flow to automate a process between Bookings and Books. When someone uses Bookings to schedule time with me I use Flow to automatically add the person as a customer in books, then create a Quote in Books for the type of consultation they
Different Canvas for Different account type
I would like to have a separate canvas for Customers and Resellers that auto-applies when I enter an ACCOUNT. Is this do-able?
IMAP sync issues in Zoho CRM
We are using the Zoho CRM for a while, and we sync (via IMAP) our Google Apps email system. The sync works properly when looking at emails per account, contact or deal, etc. However, it does not function well in the "Messages" and "SalesSigns" features.
Reporting tags for custom modules
Hi, it could be very useful. At field level and at sub table level. Thanks, Eduardo
Can't pass Dates and use date filtered Charts in Pages?
I don't mess with pages very much, but I'm trying to build a dashboard. I have a search element and several charts that need to be filtered. I also have a stateless form for a start/end date picker I am trying to use to filter data for the charts. Here
ZOHO FSM Trial - Assets
Hi I am currently using Zoho CRM and looking at adding FSM. I am trialing FSM at the moment, to potentially move away from my current programme (SimPro) but have a query on the Asset system within FSM It looks like you can only create 1 asset "type";
Next Page