There's a new version of the HubSpot API
As of November 30, 2022, HubSpot API Keys are being deprecated and are no longer supported. Continued use of HubSpot API Keys is a security risk to your account and data. Your API Keys could be deactivated at any time after Nov. 30th, and we recommend that you migrate to Private Apps as soon as possible so you do not lose business-critical functionality.
Please note: starting July 14th, 2022, net new developers can no longer build using the Ecommerce Bridge API. The API will be officially sunsetted on December 1, 2022.
Learn more about this change and how to migrate an existing Ecommerce Bridge integration.
The Ecommerce Bridge API (EB) provides a way for integrators to sync ecommerce data into HubSpot. It also facilitates creating a set of out-of-box ecommerce features for HubSpot users. These features include:
To begin using Ecommerce Bridge, you'll need to know how ecommerce data is structured in HubSpot and how to take advantage of the features that build on our ecommerce framework.
To use EB you need to:
In order to use EB you must describe how the structure of data in your system maps to native objects in HubSpot.
EB allows you to map to properties of the following native HubSpot objects:
Properties store all information about objects in HubSpot. For more information about using properties in HubSpot see this blog post and the developer guide.
Your ecommerce data can be mapped to HubSpot object properties in several ways:
Object | Property name | Type | Description |
---|---|---|---|
Product | ip__ecomm_bridge__image_url |
String | URL of an image of the product. This image will be used in the product library and ecommerce emails. |
Deal | ip__ecomm_bridge__abandoned_cart_url |
String | URL to recover the customer's cart for an order that has been abandoned. This will be used in ecommerce emails. |
Deal | ip__ecomm_bridge__discount_amount |
Decimal | The discount on an order as an amount of currency. |
Deal | ip__ecomm_bridge__order_number |
String | A unique numeric identifier for the order. |
Deal | ip__ecomm_bridge__tax_amount |
Decimal | The tax on the order as an amount of currency. |
Line Item | ip__ecomm_bridge__discount_amount |
Decimal | The discount on the line item as an amount of currency. |
Once you've decided how to map your ecommerce data to HubSpot, you can create property mappings that EB will use to sync. A property mapping is simply the name of a property in your system, the internal name of a HubSpot property, and optionally a data type that describes the format of the property. They are modified through settings.
Your settings have the following fields:
Field name | Field type | Description |
---|---|---|
enabled |
Boolean | Whether or not this application can sync data. Set this false to pause the sync from your application for maintenance or other reasons. |
webhookUri |
String, URI | Optional. The URI that HubSpot should use to start an import of an account's data. Learn more about imports. |
mappings |
Map | Map of ecommerce object type (CONTACT , PRODUCT , DEAL , LINE_ITEM ) to property mappings for that object type. |
Let's say your ecommerce platform represents a shopper by name
, email
, and phone number
. You might also represent unique orders with a name, status, URL, and a timestamp for when the order was completed. You could then define your EB settings as follows:
PUT https://api.hubapi.com/extensions/ecomm/v2/settings?appId={yourAppId}&hapikey={yourDeveloperAccountHapikey}
{ "enabled": true, "webhookUri": null, "mappings": { "CONTACT": { "properties": [ { "externalPropertyName": "firstname", "hubspotPropertyName": "firstname", "dataType": "STRING" }, { "externalPropertyName": "familyname", "hubspotPropertyName": "lastname", "dataType": "STRING" }, { "externalPropertyName": "customer_email", "hubspotPropertyName": "email", "dataType": "STRING" }, { "externalPropertyName": "phone_number", "hubspotPropertyName": "mobilephone", "dataType": "STRING" } ] }, "DEAL": { "properties": [ { "externalPropertyName": "purchase_date", "hubspotPropertyName": "closedate", "dataType": "STRING" }, { "externalPropertyName": "name", "hubspotPropertyName": "dealname", "dataType": "STRING" }, { "externalPropertyName": "stage", "hubspotPropertyName": "dealstage", "dataType": "STRING" }, { "externalPropertyName": "abandoned_cart_url", "hubspotPropertyName": "ip__ecomm_bridge__abandoned_cart_url", "dataType": "STRING" } ] }, "PRODUCT": { "properties": [ { "externalPropertyName": "product_description", "hubspotPropertyName": "description", "dataType": "STRING" }, { "externalPropertyName": "price", "hubspotPropertyName": "price", "dataType": "NUMBER" }, { "externalPropertyName": "product_name", "hubspotPropertyName": "name", "dataType": "STRING" } ] }, "LINE_ITEM": { "properties": [ { "externalPropertyName": "tax_amount", "hubspotPropertyName": "tax", "dataType": "NUMBER" }, { "externalPropertyName": "num_items", "hubspotPropertyName": "quantity", "dataType": "NUMBER" }, { "externalPropertyName": "price", "hubspotPropertyName": "price", "dataType": "NUMBER" }, { "externalPropertyName": "discount_amount", "hubspotPropertyName": "discount", "dataType": "NUMBER" } ] } } }
Note: When developing a custom solution for an individual HubSpot account, the appId
can be omitted and the API key for that account should be used instead.
The above request does not create any properties in HubSpot. But whenever your integration references a contact phone_number
, EB will modify the contact's mobilephone
property. This means that when sending ecommerce data to HubSpot through EB you can continue to use your own terminology and property names. HubSpot will handle the conversion.
Note: The property mapping for a Product image URL should be defined as a AVATAR_IMAGE dataType.
{
"externalPropertyName": "product_image",
"hubspotPropertyName": "ip__ecomm_bridge__image_url",
"dataType": "AVATAR_IMAGE"
}
More information about how to set up your property mappings is in the Settings API documentation.
Some properties are required to create an object in the HubSpot CRM. Because of this, all required properties must be mapped to and must be included when attempting to create an object. Below are a list of required properties. Mappings for these properties must be provided before you can enable your Ecommerce Bridge settings.
Required Contact Properties:
email
-- Only contacts with valid email addresses will be created.Required Deal Properties:
dealstage
-- Only deals with a valid deal stage in the ecommerce Pipeline will be created.Required Line Item Properties:
hs_assoc__deal_id
- Only line items associated to a deal will be created.
hs_assoc__product_id
- Only line items associated to a product will be created.
Required Product Properties:
None
An ecommerce store is not currently represented as a native object in HubSpot. Instead, defining a store through EB is a way to organize and manage data, and all data sent through EB will be attributed to a store.
Users will be able to segment data based on the store it came from, and will be able to see separate overviews and import tools for each store.
A store has the following fields:
Field name | Field type | Description |
---|---|---|
id | String | The identifier you use for your store. |
label | String | A human readable title for the store. This will be used in several places in the HubSpot UI. It should clearly and uniquely identify this store for users. |
adminUri | String, valid URI | Optional. An address to the website where a user can manage their store in your ecommerce system. This will allow a user to get there directly from the HubSpot UI. |
For example, when a user connects your integration to their HubSpot account you can create a store as follows:
PUT https://api.hubapi.com/extensions/ecomm/v2/stores
{ "id": "ecommercebridge-test-store", "label": "Ecommerce Bridge Test Store", "adminUri": "ecommercebridge-test-store.myshopify.com" }
With OAuth token in the Authorization header, see OAuth 2.0.
Note: When developing a custom solution for an individual HubSpot account, the OAuth token can be omitted and the API key for that account should be used instead.
The first time a store is defined in a HubSpot account, we do some additional setup.
checkout_abandoned
, checkout_pending
, checkout_completed
, processed
, shipped
, cancelled
. All deals created through EB must have a dealstage that is a part of this pipeline.Note:
The ecommerce pipeline should not be modified. This pipeline is used by all integrations using the Ecommerce Bridge, and any updates to any store will revert this pipeline to its default label and stages.
If any of those setup items fail, then the store will not be created.
Uninstalling your app will automatically delete any stores created by your app. This will also disable any workflows that are based on the store.
After you've defined how to translate your data into HubSpot, and defined at least one store, you're ready to notify HubSpot of changes to ecommerce objects in that store. Sync messages represent a creation, update, or deletion of an object in your system that should be reflected in HubSpot.
Sync messages have the following fields:
Field name | Field type | Description |
---|---|---|
objectType |
CONTACT , PRODUCT , DEAL , LINE_ITEM |
The type of the object being changed. |
storeId |
String | The ID of the store being changed. |
messages |
Array of message objects | Note: Up to 200 messages can be submitted in the same batch. They can be for different objects of the same type. |
Messages have the following fields:
Field name | Field type | Description |
---|---|---|
externalObjectId |
String, max length 100 characters, must be in ASCII format | The ID in your system for the object being modified. |
action |
UPSERT or DELETE |
The type of change this describes. |
changedAt |
long | Optional. The epoch millisecond timestamp when the change that this message describes occurred in your ecommerce system. Providing this value is optional, but strongly recommended. If not provided, the time the message was received by HubSpot will be used instead. |
properties |
Map | Map of external property names and values for this object. These are the values that we will sync into the corresponding HubSpot object. |
associations |
Map | Map of associated object type to associated external IDs. |
For all objects synced by the Ecommerce Bridge, HubSpot will maintain a link between the externalObjectId
you provide and the corresponding HubSpot object. If a new externalObjectId
is used then a new HubSpot object will be created.
Note:
externalObjectId
value.UPSERT
messages for the same externalObjectId
will update the same object in HubSpot, with the most recent changedAt
value taking precedence.EB supports the following associations between objects:
Object type | Associated object type | Mandatory | Multiple allowed |
---|---|---|---|
Deal | Contact | No* | Yes |
Line Item | Deal | Yes | No |
Line Item | Product | Yes | No |
*Note: Since contact associations are not required to create a deal, invalid contact associations will be ignored and will not cause sync errors.
Say a user has connected your integration to their HubSpot account, and you've defined an Ecommerce Bridge Test Store
. When a vendor creates a product in your ecommerce system, you can then create that product in HubSpot:
PUT https://api.hubapi.com/extensions/ecomm/v2/sync/messages
{ "storeId": "ecommercebridge-test-store", "objectType": "PRODUCT", "messages": [ { "action": "UPSERT", "externalObjectId": "orange_widget", "properties": { "price": "100", "product_name": "Orange Widget", "product_description": "The orange widget is a wonder of modern technology." } } ] }
With oauth token in the Authorization header, see OAuth 2.0.
Note: When developing a custom solution for an individual HubSpot account, the OAuth token can be omitted and the API key for that account should be used instead.
This product will be created in the HubSpot account's Product Library (visible under Sales settings).
If a customer then makes a purchase from that same store, you can sync the corresponding contact, deal, and line items representing that transaction:
PUT https://api.hubapi.com/extensions/ecomm/v2/sync/messages
{ "storeId": "ecommercebridge-test-store", "objectType": "CONTACT", "messages": [ { "action": "UPSERT", "changedAt": "1542092841947", "externalObjectId": "daniel452834529", "properties": { "firstname": "Daniel", "lastname": "Smith", "customer_email": "danielsmith@gmail.com", "phone_number": "123-456-7890" } } ] }
PUT https://api.hubapi.com/extensions/ecomm/v2/sync/messages
{ "storeId": "ecommercebridge-test-store", "objectType": "DEAL", "messages": [ { "action": "UPSERT", "changedAt": "1542092841947", "externalObjectId": "1000", "properties": { "name": "1000", "stage": "processed", "purchase_date": "1542092841947" }, "associations": { "CONTACT": [ "daniel452834529" ] } } ] }
PUT https://api.hubapi.com/extensions/ecomm/v2/sync/messages
{ "storeId": "ecommercebridge-test-store", "objectType": "LINE_ITEM", "messages": [ { "action": "UPSERT", "changedAt": "1542092841947", "externalObjectId": "abcdef", "properties": { "price": "100", "num_items": "2", "tax_amount": "7" }, "associations": { "DEAL": [ "1000" ], "PRODUCT": [ "orange_widget" ] } } ] }
The above calls will create a contact with one deal visible on the contact record. That deal will reflect the line item and show that two (2) Orange Widgets were purchased. If multiple products were purchased in the same deal, then multiple line items should be created.
Note: A customer order will have a deal stage of Checkout Abandoned in HubSpot if the order is created and not completed within 24 hours. After 24 hours pass, the order will move from Checkout Pending to Checkout Abandoned.
EB will asynchronously apply changes from these sync messages to HubSpot. This process involves translating messages using the property mappings, validating against the current state of the user's properties, and then applying property changes to users' accounts.
A successful response from the API does not mean that a change was made to a HubSpot object, just that the message was successfully enqueued. There are two endpoints you should use to monitor the success status of your sync messages.
This first, /sync/status
, returns the status of the sync for a specific external object.
GET https://api.hubapi.com/extensions/ecomm/v2/sync/status/ecommercebridge-test-store/CONTACT/daniel452834529
{ "lastProcessedAt": "1542094119555", "hubspotId": 5402, "errors": [], "objectType": "CONTACT", "storeId": "ecommercebridge-test-store", "externalObjectId": "daniel452834529" }
But, for example, say you did not include customer_email
as a property when syncing information about Daniel. Since email
is required to create a contact through EB, the processing would fail and you would see:
GET https://api.hubapi.com/extensions/ecomm/v2/sync/status/ecommercebridge-test-store/CONTACT/daniel452834529
{ "lastProcessedAt": null, "hubspotId": null, "errors": [{ "portalId": 9999999, "storeId": "ecommercebridge-test-store", "objectType": "CONTACT", "externalObjectId": "daniel452834529", "changedAt": "1542092841947", "erroredAt": "1542092843000", "type": "MISSING_REQUIRED_PROPERTY", "details": "more details about the error", "status": "OPEN" }], "objectType": "CONTACT", "storeId": "ecommercebridge-test-store", "externalObjectId": "daniel452834529" }
The second endpoint you should use to monitor the status of sync is /sync/errors/
. This will return all the existing errors for a specific application or account.
GET https://api.hubapi.com/extensions/ecomm/v2/sync/errors/app/{appId}?hapikey={yourDeveloperAccountHapikey}
or
GET https://api.hubapi.com/extensions/ecomm/v2/sync/errors/portal/{portalId}={yourCustomerAccountHapikey}
The API reference page describes the details of this API in more detail.