If a customer data platform (CDP) or another tool already tracks your visitors, you can pass its visitor ID into HubSpot, so the two systems can be matched later. Connecting customer data from several sources this way lets you look up a contact’s earlier, anonymous activity in the CDP once they become known in HubSpot. This article shows how to do it with HubSpot’s Forms API.
A shared visitor ID lets HubSpot and your CDP describe the same person
Once both systems carry the same ID, you can:
- Personalize marketing campaigns based on external data points
- Segment and target audiences more effectively
- Enhance lead scoring and prioritization
- Improve customer journey mapping and analysis
The Forms API can submit the ID in the background, without a visible form
HubSpot’s Forms API accepts form submissions sent from code. Paired with the visitor’s hubspotutk cookie, a background submission ties your external ID to that visitor’s HubSpot tracking record without asking them to fill anything in.
The example below sends a Mautic contact ID (the mtc_id cookie) into a custom HubSpot property called mautic_id. Mautic is just the example: swap in the cookie and property name of whichever tool holds your visitor ID (Segment’s anonymous ID, your own first-party ID, and so on).
<script>
// Function to get cookie value by name
function getCookie(name) {
var value = "; " + document.cookie;
var parts = value.split("; " + name + "=");
if (parts.length == 2) return parts.pop().split(";").shift();
}
// Prepare the form data
function prepareFormData() {
var mtc_id = getCookie('mtc_id'); // Get mtc_id cookie value
var hubspotutk = getCookie('hubspotutk'); // Get hubspotutk cookie value
return JSON.stringify({
"fields": [
{
"objectTypeId": "0-1",
"name": "mautic_id",
"value": mtc_id || "" // Use mtc_id as the external unique identifier value or empty string if not found
}
],
"context": {
"hutk": hubspotutk, // Include hubspotutk for tracking
"pageUri": window.location.href,
"pageName": document.title
}
});
}
// Function to submit form data
function submitToHubSpot() {
// Check if the form has already been submitted by looking up 'hasSubmitted' in localStorage
if (localStorage.getItem('hasSubmitted') !== 'true') {
var formData = prepareFormData();
var endpointUrl = 'https://api.hsforms.com/submissions/v3/integration/submit/XXXX/YYYY'; // Replace XXXX with your HubSpot portal ID and YYYY with your form GUID
fetch(endpointUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: formData
})
.then(function(response) { return response.json(); })
.then(function(data) {
console.log('Form submission successful', data);
// Set 'hasSubmitted' to 'true' in localStorage to indicate submission has occurred
localStorage.setItem('hasSubmitted', 'true');
})
.catch(function(error) {
console.error('Form submission error:', error);
});
}
}
// Run the submission function conditionally
// Check if the form should not be submitted based on 'hasSubmitted' in localStorage
if (!window.location.href.includes('gtm') && localStorage.getItem('hasSubmitted') !== 'true') {
submitToHubSpot();
}
</script>
In this code example:
- The
getCookiefunction is used to retrieve the values of themtc_idandhubspotutkcookies. - The
prepareFormDatafunction constructs the form data payload to be submitted to HubSpot. It includes themtc_idvalue as the external unique identifier in themautic_idfield, along with thehubspotutkvalue in the context object. - The
submitToHubSpotfunction checks if the form has already been submitted by looking up thehasSubmittedflag inlocalStorage. If the form hasn’t been submitted, it proceeds with the submission. - The
endpointUrlvariable should be updated with your HubSpot portal ID (replaceXXXX) and the form GUID (replaceYYYY) that you want to submit the data to. - The form data is submitted to HubSpot using the Fetch API, with the
formDataas the request body. - If the submission is successful, a success message is logged to the console, and the
hasSubmittedflag is set to'true'inlocalStorageto prevent duplicate submissions. - If an error occurs during the submission, an error message is logged to the console.
- The
submitToHubSpotfunction is conditionally executed based on the URL and thehasSubmittedflag inlocalStorage. This ensures that the form is not submitted on certain pages (e.g., GTM pages) and prevents duplicate submissions.
Please note that you need to replace XXXX with your actual HubSpot portal ID and YYYY with the form GUID you want to submit the data to.
Create the mautic_id property (or your own ID property) in HubSpot and add it to the form before you deploy the script, and test it in a sandbox or test portal first.
Run it only with consent, and only once per visitor
- Fire the script only after the visitor has accepted analytics or marketing cookies, and mention the data sharing in your privacy policy.
- Implement error handling and retry mechanisms to handle potential API failures or network issues.
- Avoid submitting duplicate form data by tracking submission status using browser storage or cookies.
- Regularly monitor and analyze the integration’s performance and data quality to ensure accuracy and reliability.
Once the visitor becomes a contact, their earlier activity is one lookup away
When the visitor later submits their email, HubSpot links the tracking cookie’s earlier page views to the new contact. Check on a test contact that your ID property came across too; if it didn’t, also send the ID as a hidden field on your real forms. You can then pull that person’s anonymous history from your CDP, which often holds more detail than HubSpot’s own page-view record.
If you also want to send custom events from your CDP into HubSpot (not just the ID), check your HubSpot subscription first: custom behavioral events aren’t available on every tier.
