Setting Up A Hubspot Buyer Within Lead Prosper
How to Set Up a HubSpot Buyer Using a Ping Post Buyer in Lead Prosper
This guide walks you through setting up HubSpot as a buyer inside Lead Prosper using a Ping Post configuration.
This approach allows you to:
- PING HubSpot first to check whether a contact already exists (duplicate check)
- POST the lead only if it does not exist, creating a new contact in HubSpot
Why HubSpot Uses a Ping Post Setup
HubSpot does not natively reject duplicate contacts during creation in a way that Lead Prosper can reliably interpret as an “Accepted” or “Rejected” outcome.
Using a Ping Post buyer solves this by:
PING (Duplicate Check)
Querying HubSpot to see if a contact with the same email or phone already exists.
POST (Contact Creation)
Creating the contact only when the duplicate check confirms the lead does not already exist.
This ensures
- Clean data in HubSpot
- Accurate lead acceptance logic in Lead Prosper
- Predictable buyer behavior during routing
We will be using the CRM API from Hubspot. If you have any questions related specifically to the Hubspot API please review their Official CRM API Documentation - https://developers.hubspot.com/docs/guides/crm/understanding-the-crm
Prerequisites
Before starting, you must have:
- Access to the HubSpot account receiving leads
- Permission to create a HubSpot Private App
- Knowledge of your HubSpot contact property names
- An existing Lead Prosper campaign
How to Generate a HubSpot Private App API Key
HubSpot no longer uses legacy API keys. Instead, authentication is handled via Private App Access Tokens.
Step-by-Step Instructions
In HubSpot, navigate to:
Settings → Integrations → Private Apps
- Click Create private app
Give the app a clear name, such as:
Lead Prosper Contact Sync- Under Scopes, enable at minimum:
crm.objects.contacts.readcrm.schemas.contacts.readcrm.objects.contacts.write
- Click Create app
- Copy the Access Token
This token is used as a Bearer token in the Authorization header for both the PING and POST requests in Lead Prosper.
For more details on how to generate the Private App Token please read the official Hubspot Documentation - https://developers.hubspot.com/docs/apps/legacy-apps/private-apps/overview
How to Retrieve HubSpot Contact Property Names
Why Property Names Matter
When posting data into HubSpot, you must use the internal property name, not the label shown in the UI.
Example: - Label: First Name - Property name: firstname
How to Retrieve Property Names via API
You can issue an API request to the Properties API in order to read all fields available in the CRM. More about the Properties API can be found in the official Hubspot docs: https://developers.hubspot.com/docs/api-reference/crm-properties-v3/core/get-crm-v3-properties-objectType. You can use tools like Postman or similar to make this API request, as this is an intermediary, but required step, before setting up the buyer. Alternatively, you can use Lead Prosper, by creating a direct post buyer in a different campaign with the following configuration and saving the test output somewhere, as it will be needed in the next steps.
Method GET
URL https://api.hubapi.com/crm/v3/properties/0-1
Headers Authorization: Bearer {{api_key}}
The response will contain multiple different fields. The 2 most common will be these:
{
"updatedAt": "2024-09-05T17:14:04.747Z",
"createdAt": "2019-08-06T02:41:08.029Z",
"name": "firstname",
"label": "First Name",
"type": "string",
"fieldType": "text",
"description": "A contact's first name",
"groupName": "contactinformation",
"options": [],
"displayOrder": 0,
"calculated": false,
"externalOptions": false,
"hasUniqueValue": false,
"hidden": false,
"hubspotDefined": true,
"modificationMetadata": {
"archivable": true,
"readOnlyDefinition": true,
"readOnlyValue": false
},
"formField": true,
"dataSensitivity": "non_sensitive"
}
{
"updatedAt": "2024-02-27T21:19:50.121Z",
"createdAt": "2024-02-27T21:19:50.121Z",
"name": "lead_status",
"label": "Lead Status",
"type": "enumeration",
"fieldType": "select",
"description": "Lead Status",
"groupName": "contactinformation",
"options": [
{
"label": "New",
"value": "New",
"displayOrder": 0,
"hidden": false
},
{
"label": "Qualified",
"value": "Qualified",
"displayOrder": 1,
"hidden": false
}
],
"createdUserId": "1",
"updatedUserId": "1",
"displayOrder": -1,
"calculated": false,
"externalOptions": false,
"archived": false,
"hasUniqueValue": false,
"hidden": false,
"showCurrencySymbol": false,
"modificationMetadata": {
"archivable": true,
"readOnlyDefinition": false,
"readOnlyValue": false
},
"formField": false,
"dataSensitivity": "non_sensitive"
}
In both examples, pay attention to the name attribute. That is what you will need to use later when configuring the payload in Lead Prosper.
If the field type is select, pay attention to the options values. That's the only values that a given field will accept, so you might have to use computed fields and transformers to remap the data before sending it to this buyer.
Creating the Buyer in Lead Prosper
- Navigate to Buyers in Lead Prosper
- Click Create New Buyer
- Select Ping Post Buyer
Configuring the PING (Duplicate Check)
Endpoint & Method
POST https://api.hubapi.com/crm/v3/objects/contacts/search
Headers
Authorization: Bearer {{api_key}}
Example Request Body
{
"filterGroups": [
{
"filters": [
{
"propertyName": "email",
"operator": "EQ",
"value": "{{email}}"
}
]
},
{
"filters": [
{
"propertyName": "phone",
"operator": "EQ",
"value": "{{phone}}"
}
]
}
],
"properties": [
"email",
"phone"
],
"limit": 1
}
Response Mapping
- Key: total
- Condition: equal with
- Value: 0
Configuring the POST (Create Contact)
Endpoint & Method
POST https://api.hubapi.com/crm/v3/objects/contacts
Example Request Body
{
"properties": {
"email": "{{email}}",
"firstname": "{{first_name}}",
"lastname": "{{last_name}}",
"phone": "{{phone}}"
}
}
Response Mapping
- Key: id
- Condition: equal with
- Value: *
Testing & Troubleshooting
- Use the Test Buyer tool
- Expect Accepted when
total = 0andidis returned - Use the Response Parser Tool if needed- https://support.leadprosper.io/article/287-using-the-upgraded-response-parser-to-simplify-buyer-setups
With this Ping Post buyer in place, HubSpot will only receive leads that pass your duplicate check, ensuring clean contact creation and predictable routing behavior inside Lead Prosper. If you make changes to your HubSpot contact schema or add new required properties, be sure to revisit both the PING filters and POST mappings to keep everything aligned. When in doubt, coordinate with the HubSpot account owner and re-run buyer tests to confirm expected results before sending live traffic.
If you have any questions please open a Support Ticket by emailing us at support@leadprosper.io.