Let’s Talk

How to Sync Website Users to HubSpot Using PHP

Integrating your website directly with HubSpot allows you to automatically sync user data without relying on manual exports or third-party form tools.

This is especially useful for membership sites, SaaS platforms, and any application where users register and update their details directly on your system.

In this guide, we’ll build a simple PHP integration using the official HubSpot SDK that will allow you to create, update, and manage contacts automatically.

Step 1: Install the HubSpot SDK

Install the official HubSpot PHP SDK using Composer:

composer require hubspot/api-client

Then include Composer’s autoloader in your project:

require_once 'vendor/autoload.php';

Step 2: Create a HubSpot Private App

To connect your application to HubSpot, you need an access token from a Private App.

Store your token securely using an environment variable:

$accessToken = getenv('HUBSPOT_ACCESS_TOKEN');

Step 3: Create the HubSpot Class

Create a simple service class to initialise the HubSpot client.

<?php

use HubSpot\Factory;
use HubSpot\Client\Crm\Contacts\Model\Filter;
use HubSpot\Client\Crm\Contacts\Model\FilterGroup;
use HubSpot\Client\Crm\Contacts\Model\PublicObjectSearchRequest;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectInput;

class Hubspot
{
    private $client;

    public function __construct()
    {
        $this->client = Factory::createWithAccessToken(
            getenv('HUBSPOT_ACCESS_TOKEN')
        );
    }
}

Step 4: Map User Data to HubSpot Properties

Before sending data to HubSpot, map your user object to HubSpot’s contact properties. Also include any custom properties you may have created within Hubspot.

public function assignUserProperties($user)
{
    if (!$user->userid) {
        return false;
    }

    return [
        'user_id' => $user->userid,
        'email' => $user->email,
        'phone' => $user->tel_code . $user->tel,
        'firstname' => $user->fname,
        'lastname' => $user->lname,
        'subscribed' => $user->subscribed,
        'subscription_start_date' => $user->sub_start,
        'subscription_expiry_date' => $user->sub_expire,
        'last_login' => $user->last_login,
    ];
}

Step 5: Check for Existing Contacts

Check whether the email already exists in HubSpot to avoid duplicates.

public function searchContacts($property, $value)
{
    $filter = new Filter([
        'property_name' => $property,
        'operator' => 'EQ',
        'value' => $value
    ]);

    $filterGroup = new FilterGroup([
        'filters' => [$filter]
    ]);

    $searchRequest = new PublicObjectSearchRequest([
        'filter_groups' => [$filterGroup],
        'limit' => 1
    ]);

    $results = $this->client
        ->crm()
        ->contacts()
        ->searchApi()
        ->doSearch($searchRequest);

    if (count($results->getResults()) > 0) {
        return $results->getResults()[0]->getId();
    }

    return false;
}

Step 6: Create a Contact

Create a new one in HubSpot (automatically check for duplicates).

public function addContact($user)
{
    $existingId = $this->searchContacts('email', $user->email);

    if ($existingId) {
        // UPDATE DATABASE; contact already exists in Hubspot, update `hubspot_contactid` in user table with $existingId

        return true;
    }

    $contact = new SimplePublicObjectInput([
        'properties' => $this->assignUserProperties($user)
    ]);

    try {
        $response = $this->client
            ->crm()
            ->contacts()
            ->basicApi()
            ->create($contact);

        $hubspotId = $response->getId();

        // You need to store the $hubspotId in your database here

        return true;

    } catch (Exception $e) {
        return false;
    }
}

Step 7: Update a Contact

When a user updates their account, we push the changes to HubSpot. If the user doesn’t already have a hubspot_contactid add a new contact instead.

public function updateContact($user)
{
    if (!$user->hubspot_contactid) {
        return $this->addContact($user);
    }

    $contact = new SimplePublicObjectInput([
        'properties' => $this->assignUserProperties($user)
    ]);

    try {
        $this->client
            ->crm()
            ->contacts()
            ->basicApi()
            ->update(
                $user->hubspot_contactid,
                $contact
            );

        // UPDATE DATABASE; I recommend having a `hubspot_last_updated` field to update in the users table, or some sort of log so you can track what's going on

        return true;

    } catch (Exception $e) {
        return false;
    }
}

Step 8: Delete a Contact

You can also archive contacts in HubSpot if needed i.e. when admin or the user themselves deletes a user account.

public function deleteContact($contactId)
{
    if (!$contactId) {
        return false;
    }

    try {
        $this->client
            ->crm()
            ->contacts()
            ->basicApi()
            ->archive($contactId);

        return true;

    } catch (Exception $e) {
        return false;
    }
}

Note that in the try/catch blocks you’ll want to deal with and log errors properly.

This code is free to use at your own discretion. It comes without warranty. Please feel free to feedback any edits.