There are cases where you may approach the 50,000 company-associated emails limit in HubSpot e.g. when your customer is a large company and they have been a customer for years.

When you reach 80% of the limit, HubSpot will issue a warning. This should give you a plenty of time to address the issue. If manage to actually hit the limit, no new association between company and email will be created past the limit, which will no doubt make your marketing and sales staff unhappy.

Unfortunately HubSpot hasn’t provided an elegant way to solve this problem (i.e. to prune older company-email associations).

Solution

Following tutorial assumes that you are a software developer. If you are not, please consider hiring one, as the solution is beyond the powers of a casual HubSpot user.

While each case may be a bit different, reasonable solution is to prune oldest 10,000 company-email associations. This would not delete old emails, but would simply disassociate them from the company.

You would do this by using HubSpot API and your favourite programming language (whatever that may be: NodeJS, PHP, Java, …).

First you’ll want to obtain the company ID (object ID). This is easily obtained from the HubSpot notification you got when limit was approached.

Next fetch all of the associated company emails IDs using HubSpot CRM Associations API. Request should look something like this:

PHP
<?php 

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.hubapi.com/crm/v4/objects/0-2/'.$company_id.'/associations/0-49',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'GET',
  CURLOPT_HTTPHEADER => array(
    'Authorization: Bearer '.$hubspot_private_app_access_token
  ),
));

$result = curl_exec($curl);

?>

Fetch all associated emails (we just need email IDs for now) and save them to a file for later.

Unfortunately Association API does not return the email send dates, which we need in order to disassociated only the older email, so we have to fetch that using another API call.

Let’s get email details (we care primarily about email send dates) using Email Batch Read call from API v3 and save them to a file:

PHP
<?php 

$curl = curl_init();

$body_params['inputs'] = array();

foreach ($email_ids as $email_id) {
  $body_params['inputs'][] = array(
    "id" => $email_id
  );
}

$body_params_json = json_encode($body_params);

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.hubapi.com/crm/v3/objects/emails/batch/read',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => $body_params_json,
  CURLOPT_HTTPHEADER => array(
    'Authorization: Bearer '.$hubspot_private_app_access_token,
    'Content-Type: application/json'
  ),
));
$result = curl_exec($curl);

?>

We now have a list of emails (and send dates) associated with the company and we can decide what associations to prune. Reasonable option is to prune 10,000 oldest email as these are usually least relevant.

We’d prune the email associations using Associations Batch Archive call from HubSpot API v3.

Calls should look something like this:

PHP
<?php 

$data = array();

foreach ($batch as $email_id) {
  $data['inputs'][] = array(
    'from' => array(
      'id' => $company_id
    ),
    'to' => array(
      'id' => $email_id
    ),
    'type' => 'company_to_email'
  );
}

$curl = curl_init();
curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.hubapi.com/crm/v3/associations/0-2/0-49/batch/archive',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => json_encode($data),
  CURLOPT_HTTPHEADER => array(
    'Authorization: Bearer '.$hubspot_private_app_access_token,
    'Content-Type: application/json'
  ),
));    
$result = curl_exec($curl);

curl_close($curl);

?>

That is it! You’re done – at least until next time you reach the association limit – at which point you should run the process all over again :-).

Automating the pruning process is possible, but likely not worth it. Hitting the limit is rare and you may want to customize the pruning process for each incident.

HubSpot has increased the limit from 10,000 to 50,000 in 2022. Perhaps in future they will increase this even more.