
I’ve been quite busy recently, working on a project involving the bidirectional syncing of user data between a client’s WordPress site and their SugarCRM platform via the SugarCRM API. As part of that work, I needed to create a contact in SugarCRM with the Sugar API programmatically, which turned out to be straightforward once I understood the basics. It’s actually been a lot of fun, and even dealing with the SugarCRM docs hasn’t been terrible 😅.
Anywho, in this SugarCRM tutorial, I’ll show you how to connect, and authenticate to the SugarCRM REST API, and create contacts programmatically. Following this tutorial, you’ll be able to use the code as a base to build integrations for lead/contact capture, data syncing, automation workflows etc etc.
The flavour of SugarCRM I will be working with in this tutorial is Sugar Enterprise but the code should work with all SugarCRM editions including Professional, Enterprise, Ultimate, and cloud versions (Sugar Sell/Serve). The REST API is identical across all editions.
What You’ll Learn
- Authenticating with SugarCRM’s OAuth2 API.
- Creating contact records via the REST API v11.
- Building a reusable PHP class for SugarCRM.
Requirements
- SugarCRM instance with API access (obviously), sandbox or production is fine.
- PHP with cURL enabled.
- Basic PHP knowledge.
Righto, let’s begin our tutorial on ‘how to create a contact in SugarCRM with the Sugar API & PHP‘!
Table of Contents
1. First Steps On Creating a Contact in SugarCRM With the Sugar API
We first need to create our project files:
config.php
– Our SugarCRM credentials.bootstrap.php
– Loads config, and provides an authenticated SugarCRM connection.sugarcrm.php
– Our PHP class that will handle auth and API interactions.get-fields.php
– Lists all available fields for the Contacts module.index.php
– Script that will hold our contact fields data, push data to Sugar & error check.
2. Creating the Sugar Config File
This file should be outside of the public root directory on your server, and the file permissions should be set to 600!
The very first file we will create is the config file. This will hold all of the information about our specific SugarCRM workspace, and as mentioned above, this file should be placed outside of the public_html
(or www
, htdocs
) directory to prevent it from being potentially accessible via an HTTP request.
- config.php
<?php
return [
'url' => 'https://your-instance.sugarcrm.com',
'username' => 'your_username',
'password' => 'your_password',
'client_id' => 'sugar',
'platform' => 'base',
'module' => 'Contacts',
'timeout' => 30,
'verify_ssl' => true
];
Most of the above should be fairly straightforward, but below are some parameters that I had to double check.
module
- If you would like to capture leads instead of contacts, change'module' => 'Contacts'
to'module' => 'Leads'
.client_id
- The default value forclient_id
issugar
.platform
- Defaults tobase
.
In my server, I will place this config.php
file inside a directory called sugarcrm
, in my website's root directory.
logs/
public_html/
sugarcrm/
└── config.php
3. Creating the Bootstrap File
Right, so we’ve got our config file sorted. Now we need a way to load everything without copy-pasting the same setup into every single file. That’s where bootstrap.php
comes in – it’s the entry point for all our SugarCRM files, and provides a reusable connection to the SugarCRM API.
Here’s what it does:
- Provides a helper function - gives us an easy, reusable way to get an authenticated connection.
- Loads the SugarCRM class - the one we’ll build next to handle all the API magic.
- Grabs our config - pulls in those credentials we just set up.
- bootstrap.php
<?php
require_once 'sugarcrm.php';
$configPath = '/home/frontend/sugarcrm/config.php';
if (!file_exists($configPath)) {
die('Configuration file not found.');
}
$config = require $configPath;
if (!isset($config['url']) ||
!isset($config['username']) ||
!isset($config['password']) ||
!isset($config['client_id']) ||
!isset($config['platform'])) {
die('Invalid configuration file.');
}
function getSugarConnection($config) {
static $sugar = null;
if ($sugar === null) {
$sugar = new SugarCRM($config);
$sugar->authenticate();
}
return $sugar;
}
Notes
- Includes a soon to be created
sugarcrm.php
file that will handle all of our SugarCRM functionality. - Singleton pattern – prevents creating multiple API connections by reusing the same instance. Implemented using the
static
keyword, which preserves the variable's value across function calls. getSugarConnection()
returns the same authenticated instance on every call. Creates new connection only on first invocation.- Validation checks - Fail fast with clear error messages if config file is missing or incomplete.
4. Creating the sugarcrm.php File
Next up, we're going to code the brains of the operation, the sugarcrm.php
file. This will be a PHP class that connects to, and interacts with SugarCRM's REST API using OAuth2 authentication.
- sugarcrm.php
<?php
class SugarCRM {
private $url;
private $username;
private $password;
private $clientId;
private $platform;
private $accessToken;
private $timeout;
private $verifySSL;
public function __construct($config) {
}
public function authenticate() {
}
public function createContact($contactData, $module = null) {
}
public function getModuleFields($module = 'Contacts') {
}
private function makeRequest($url, $method = 'GET', $data = null, $headers = []) {
}
}
Notes
- We first create a class called
SugarCRM
that encapsulates all the functionality needed to connect to and interact with SugarCRM's API. - The first method we create is the constructor, which accepts a
$config
parameter - an associative array containing all your connection details (URL, username, password etc). It extracts these values and stores them in private properties for use throughout the class. - The authenticate() method logs into SugarCRM using OAuth2 password grant flow and stores an access token that's used for all subsequent API calls.
- The createContact() method accepts two parameters. The first parameter
$contactData
is an array of field names and values that you want to save (like first name, last name, email, etc.) This data comes from wherever you call the method, such as from ourindex.php
file. The second parameter$module
is optional and specifies which SugarCRM module to create the record in, defaulting to Contacts if you don't specify one. - The getModuleFields() method retrieves metadata about all available fields in a module, showing you what fields exist, their types, and their validation rules.
- The makeRequest() private method is the workhorse of the class and handles all the actual HTTP communication using cURL, managing headers, timeouts, and error handling for all the public methods.
4.1 Creating the __construct() Method
The constructor is basically the setup wizard for our class, it runs automatically when we create a new SugarCRM
object and loads all of our connection details into place.
- sugarcrm.php / __construct()
public function __construct($config) {
$this->url = rtrim($config['url'], '/');
$this->username = $config['username'];
$this->password = $config['password'];
$this->clientId = $config['client_id'];
$this->platform = $config['platform'];
$this->timeout = $config['timeout'] ?? 30;
$this->verifySSL = $config['verify_ssl'] ?? true;
}
4.2 Creating the authenticate() Method
The authenticate()
method... authenticates with SugarCRM's OAuth2 API :) by sending credentials to the token endpoint. On success, it stores the returned access_token
for use in subsequent API requests. If authentication fails, it throws an exception with error details.
- sugarcrm.php / authenticate()
public function authenticate() {
$authUrl = $this->url . '/rest/v11/oauth2/token';
$authData = [
'grant_type' => 'password',
'client_id' => $this->clientId,
'username' => $this->username,
'password' => $this->password,
'platform' => $this->platform
];
$response = $this->makeRequest($authUrl, 'POST', $authData);
if (isset($response['access_token'])) {
$this->accessToken = $response['access_token'];
return true;
}
throw new Exception('Authentication failed: ' . json_encode($response));
}
4.3 Creating the createContact() Method
This createContact()
method creates a new contact (or record in any specified module) in SugarCRM. It first verifies authentication, then constructs the API endpoint URL using the module name (defaulting to 'Contacts'), and sends a POST request with the contact data and OAuth token. The method returns SugarCRM's response, which includes the newly created record with its assigned ID and all field values.
- sugarcrm.php / createContact()
public function createContact($contactData, $module = null) {
if (!$this->accessToken) {
throw new Exception('Not authenticated. Call authenticate() first.');
}
$module = $module ?? 'Contacts';
$createUrl = $this->url . '/rest/v11/' . $module;
$response = $this->makeRequest($createUrl, 'POST', $contactData, [
'OAuth-Token: ' . $this->accessToken
]);
return $response;
}
4.4 Creating the getModuleFields() Method
The getModuleFields()
method retrieves the field definitions for a specified SugarCRM module (defaulting to 'Contacts'). It sends a GET request to the metadata endpoint, which returns information about all available modules and their fields. The method extracts and returns only the fields array for the requested module, or throws an exception if the module doesn't exist in the metadata response.
- sugarcrm.php / getModuleFields()
public function getModuleFields($module = 'Contacts') {
if (!$this->accessToken) {
throw new Exception('Not authenticated. Call authenticate() first.');
}
$metadataUrl = $this->url . '/rest/v11/metadata';
$response = $this->makeRequest($metadataUrl, 'GET', null, [
'OAuth-Token: ' . $this->accessToken
]);
if (isset($response['modules'][$module]['fields'])) {
return $response['modules'][$module]['fields'];
}
throw new Exception("Module '$module' not found in metadata");
}
4.5 Creating the makeRequest() Method
This private method handles all HTTP communication with the SugarCRM API using cURL. It configures the request with appropriate headers, timeout settings, and SSL verification, then JSON-encodes and sends the provided data in a POST request. It checks for both cURL errors and HTTP error status codes (400+), throwing exceptions if problems occur, and returns the decoded JSON response as a PHP array.
- sugarcrm.php / makeRequest()
private function makeRequest($url, $method = 'GET', $data = null, $headers = []) {
$ch = curl_init($url);
$defaultHeaders = ['Content-Type: application/json'];
$headers = array_merge($defaultHeaders, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->verifySSL);
if ($method === 'POST') {
curl_setopt($ch, CURLOPT_POST, true);
if ($data) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
}
}
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
$error = curl_error($ch);
curl_close($ch);
throw new Exception('cURL error: ' . $error);
}
curl_close($ch);
$decoded = json_decode($response, true);
if ($httpCode >= 400) {
throw new Exception('HTTP Error ' . $httpCode . ': ' . json_encode($decoded));
}
return $decoded;
}
5. Creating the get-fields.php File
Now, with our above files created, we are now in a position to start doing some useful (and fun) stuff such as authenticating and pulling in some data! Let us create this get-fields.php
file and utilise the code in the previous files to show all available fields in our Sugar instance.
- get-fields.php
<?php
require_once 'bootstrap.php';
try {
$sugar = getSugarConnection($config);
$fields = $sugar->getModuleFields('Contacts'); ?>
<pre>
<?php
print_r($fields);
?>
</pre>
<?php
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}
Notes
- We have added our
bootstrap.php
at the top. - Then we use a try / catch block, create a new instance, connecting to our SugarCRM platform.
- Then store all available fields in the response and output them.
What we are left with is the following PHP array:
Array
(
[id] => Array
(
[name] => id
[vname] => LBL_ID
[type] => id
[required] => 1
[reportable] => 1
[duplicate_on_record_copy] => no
[comment] => Unique identifier
[mandatory_fetch] => 1
)
[name] => Array
(
[name] => name
[vname] => LBL_NAME
[type] => fullname
[fields] => Array
(
[0] => first_name
[1] => last_name
[2] => salutation
[3] => title
)
[sort_on] => last_name
[source] => non-db
[group] => last_name
[db_concat_fields] => Array
(
[0] => first_name
[1] => last_name
)
[importable] => false
[duplicate_on_record_copy] => always
)
...
)
This information is invaluable for identifying exact field names, types, and string lengths in our SugarCRM instance. For example, from the fields array, I've chosen the following field names to use when creating my SugarCRM contacts:
Field Name | Field Type |
---|---|
title | varchar |
first_name | varchar |
last_name | varchar |
description | text |
phone_work | phone |
email_address | |
primary_address_street | text |
primary_address_city | varchar |
primary_address_postalcode | varchar |
countrydd_c | enum |
do_not_call | bool |
So, now that we know which fields we’ll be populating when creating a new contact, we can go ahead and code up the final index.php
file and add a sample contact to SugarCRM via the REST API!
A little note on the countrydd_c
enum field type.
An enum (short for enumeration) is a data type that consists of a set of named, constant values. An enum field is a variable or database column that can only be assigned one of the predefined, symbolic names from this set.
So, when you're sending data to SugarCRM via the REST API, to populate the countrydd_c
field, the value you send must exactly match one of the predefined country values in SugarCRM's countries_dom
dropdown list.
6. Creating the index.php File and Adding a Contact to SugarCRM!
Now for ze moment of truth! We've got everything in place, our class is ready to go, and we've identified exactly which fields we want to populate. It's time to create the index.php
file that brings it all together and actually pushes a contact into SugarCRM.
- index.php
<?php
require_once 'bootstrap.php';
try {
$contactData = [
'title' => 'Mr',
'first_name' => 'Peter',
'last_name' => 'Smith',
'description' => 'Demo contact created via Frontend Hero API tutorial',
'phone_work' => '555-123456',
'email' => [
[
'email_address' => 'peter.smith@example.com',
'primary_address' => true
]
],
'primary_address_street' => '123 Evergreen Street',
'primary_address_city' => 'Newhaven',
'primary_address_postalcode' => 'BN9 9PE',
'countrydd_c' => 'CONGO',
'do_not_call' => 1
];
$sugar = getSugarConnection($config);
$result = $sugar->createContact($contactData, $config['module']);
echo "Contact created! ID: {$result['id']}";
// print_r($result);
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}
Notes
- Again, we include our
bootstrap.php
file at the top of the page, to authenticate to our SugarCRM workspace. - We use a try / catch block to safely handle errors, then create a
$contactData
array populated with sample contact information (name, email, phone, address, etc.). - We establish a connection to SugarCRM using
getSugarConnection()
, then callcreateContact()
to submit the contact data and receive back the newly created contact's ID and details. - To see the response from Sugar (including all field values), you can uncomment the
print_r
function.
Now, before we access the index.php
file directly, let's first add a little URL parameter check so we can control when the contact actually gets created. That way, we won't accidentally create a new contact every time we refresh the page!
- index.php
<?php
require_once 'bootstrap.php';
if (isset($_GET['action']) && $_GET['action'] === 'create') {
// existing code
} else {
echo "Add ?action=create to the URL to create a contact";
}
Now, the only way that we will be able to add a contact into SugarCRM is by appending the following to the URL:
https://www.example.com/index.php?action=create
And after appending this query parameter, and refreshing the page, the result we get now is:
Contact created! ID: 18c4b6c8-ac50-11f0-b879-a0d3c106b134
Annnnnnd we can now view this new contact in SugarCRM! 🥳

Conclusion: Creating a Contact in SugarCRM With the Sugar API & PHP
And that's it! You now (hopefully) have a solid understanding of how to create a contact in SugarCRM with the Sugar API & PHP. With this knowledge, you can expand upon this, and build some pretty powerful integrations, automate your CRM workflows, and sync data seamlessly between your systems. The possibilities are endless!
If you might need help with syncing data in your SugarCRM platform with WordPress (or any other third party platforms), you can get in touch with me here, or here to hire me ;)