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.
The Ecommerce Bridge provides a process for syncing ecommerce data into HubSpot. The Ecommerce Bridge handles much of the work of syncing data. It does the work of applying the property mappings, validating the incoming data against the customer's specific setup and applying the changes appropriately. Using the Ecommerce Bridge API you avoid all the little gotchas encountered when writing data directly to Contacts and the CRM objects.
The Ecommerce Bridge allows HubSpot to provide common ecommerce functionality. Because we're now working from a common understanding of how ecommerce data is structured, HubSpot can add new features that automatically work for all Ecommerce Bridge applications. For example, users of Ecommerce Bridge applications will have the ability to send marketing emails for new customer welcome and abandoned cart recovery -- allowing them to take advantage of HubSpot's email send infrastructure and email performance tracking. Users will also have the ability to build ecommerce reporting dashboards and use ecommerce data to build fine-tuned contact lists.
To implement an Ecommerce Bridge application you need to:
To use the Ecommerce Bridge API with a HubSpot portal you need to:
In order to implement the Ecommerce Bridge you must map the structure of data in your ecommerce domain onto objects in the HubSpot CRM. The Ecommerce Bridge allows you to map to properties of the following objects:
A property mapping is an external property name (the name in your system), a HubSpot internal property name, and a data type that tells the API how to treat property values.
More information about how to set up your property mappings is in the Settings API documentation.
Your ecommerce data can be mapped to default HubSpot properties, special properties provided by the API, or custom properties that you define. More information on developing with CRM object properties can be found in the Properties API documentation.
The Ecommerce Bridge supports the following associations between objects:
To support these cross-object associations, the Ecommerce Bridge provides some special properties.
Object | Property name | Type | Description |
---|---|---|---|
Deal | hs_assoc__contact_ids |
Comma separated list of strings |
A list of external IDs of contacts associated with the deal. Deals are not required to be associated to contacts, so this property is not required for the successful creation of a deal. Note: Since contact associations are not required, invalid contact associations will be ignored and will not cause sync errors. |
Line Item | hs_assoc__deal_id |
String | External ID of the deal associated with this line item. A valid value for this property is required for the successful creation of a line item. |
Line Item | hs_assoc__product_id |
String | External ID of the product associated with this line item. A valid value for this property is required for the successful creation of a line item. |
All IDs that are provided as values for these properties should be external IDs (the IDs of the objects in your system), not HubSpot IDs. These properties will not be defined on CRM objects, but will be used to create the associations between them.
In addition to HubSpot default properties, Ecommerce Bridge provides some properties specific to ecommerce. These properties will be defined on every portal that uses the API or installs an app built on the API.
Note: All following properties are prefixed with ip__ecomm_bridge__
. For example Order Number will be ip__ecomm_bridge__order_number
.
Object | Property name | Type | Description |
---|---|---|---|
Contact | ecomm_synced |
Boolean | This will be set to true for all contacts synced by the API |
Product | ecomm_synced |
Boolean | This will be set to true for all products synced by the API |
Product | image_url |
String | URL of an image of the product |
Deal | ecomm_synced |
Boolean | This will be set to true for all deals synced by the API |
Deal | abandoned_cart_url |
String | URL to recover the cart for a deal that has been abandoned |
Deal | discount_amount |
Decimal | The discount on the deal as an amount of currency |
Deal | order_number |
String | A unique numeric identifier for the deal |
Deal | shipment_ids |
String, comma separated list of IDs | List of all known shipment IDs associated with the deal |
Deal | tax_amount |
Decimal | The tax price on the deal as an amount of currency |
Line Item | ecomm_synced |
Boolean | This will be set to true for all line items synced by the API |
Line Item | discount_amount |
Decimal | The discount on the line item as an amount of currency |
Ecommerce Bridge will also define a deal pipeline on every portal that uses the API or installs an app built on the API. All deals created through the Ecommerce Bridge API must have a stage that is a part of the ecommerce pipeline. This means that any portal with the maximum number of deal pipelines, or an existing ecommerce Pipeline, will not be able to use the API.
ecommerce Pipeline Deal Stages: checkout_abandoned
, checkout_pending
, checkout_completed
, processed
, shipped
, cancelled
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
After you've defined how your system's properties map into HubSpot, and after a user has installed your integration, you're ready to send sync messages to HubSpot notifying HubSpot of changes to ecommerce objects. The Sync Messages section describes the details of this API.
When sending these messages, you use your system's property names. The reason for this is that HubSpot stores each of these messages in an immutable data store. This allows efficient handling of property mapping changes. When you change your property mappings, HubSpot can reapply field mappings to our full history of sync messages -- without having to reimport data from your system.
The Ecommerce Bridge API will apply changes from sync messages to HubSpot. This process is asynchronous, and involves applying the property mappings, validation against the current state of the user's properties, and the efficient bulk application of property changes to customer portals.
The Ecommerce Bridge will also be adding performance and reliability monitoring to this process as well as giving customers troubleshooting capabilities for sync issues.
The Ecommerce Bridge defines a process to allow customers to import their ecommerce data into HubSpot. Imports only apply to and are only available for application development, not development on an individual portal.
The import process is as follows:
The customer initiates an import and the HubSpot sends your API an import initialization webhook. (See: Import Initialization Webhook) This is your notification to start sending HubSpot import data for this customer.
You use the import pages endpoint to send import data. (See: Import Pages Endpoint) These import pages are similar to sync messages in that they use your property names.
When you're done sending HubSpot import data for a particular object type, you send an import-end request to HubSpot. This tells HubSpot that we have all the data for this object type. In order for an import to complete successfully, HubSpot must receive import-end notifications for each object type: Contacts, Deals, Line Items, and Products. (See: Import Page End Endpoint)
For all objects synced via the Ecommerce Bridge API we store a mapping from integratorObjectId
to the corresponding HubSpot ID. Upserts for the same integratorObjectId
will update the same object in HubSpot. If the Ecommerce Bridge API sees a new integratorObjectId
it will create a new object in HubSpot.
One exception to this rule is if we see a new integratorObjectId
for a Contact, we will first check to see if any contact exists with the same email address. If so, we will associate the new integratorObjectId
to the matching contact and update the contact's properties. If a contact does not exist with a matching email address, we will create a new Contact.
Note: When using the Ecommerce Bridge API, deals that go into the pending
state are automatically moved to abandoned
24 hours later.
Manually installing the Ecommerce Bridge API only applies to and is only available for development on an individual portal, not application development. For an ecommerce application, these install steps will happen when a customer installs the application.
To take full advantage of the functionality that Ecommerce Bridge provides, certain things need to be added to your portal. For example, this includes ecommerce specific properties and an ecommerce reporting dashboard. To add these things to your portal, use the installs endpoint.
POST /extensions/ecomm/v1/installs
No request body is expected.
Before you are able to sync data using the /sync-messages
endpoint, you must have installed and you must have settings enabled. To check the status of your setup, use the installs status endpoint.
GET /extensions/ecomm/v1/installs/status
If you want to disable ecommerce data syncing to your portal and remove ecommerce based workflows, use the uninstall endpoint.
POST /extensions/ecomm/v1/installs/uninstall
No request body is expected.
The Settings API is where you set up the property mappings for your use of the Ecommerce Bridge API.
When developing an application, use your developer portal's hapikey along with the appId to authenticate for these settings requests. When developing for an individual portal, use that portal's hapikey to authenticate and no appId is needed.
PUT /extensions/ecomm/v1/settings?appId={appId}
Example request body:
{ "enabled": false, "importOnInstall": true, "productSyncSettings": { "properties": [ { "propertyName": "my_name_field", "dataType": "STRING", "targetHubspotProperty": "name" }, { "propertyName": "image", "dataType": "AVATAR_IMAGE", "targetHubspotProperty": "ip__ecomm_bridge__image_url" } ] }, "dealSyncSettings" : { "properties": [ ] }, "lineItemSyncSettings": { "properties": [ ] }, "contactSyncSettings": { "properties": [ ] } }
This PUT
operation is an update-replace. Blank values will clear out existing data.
GET /extensions/ecomm/v1/settings?appId={appId}
Example response:
{ "enabled": false, "importOnInstall": true, "productSyncSettings": { "properties": [ { "propertyName": "my_name_field", "dataType": "STRING", "targetHubspotProperty": "name" }, { "propertyName": "image", "dataType": "AVATAR_IMAGE", "targetHubspotProperty": "ip__ecomm_bridge__image_url" } ] }, "dealSyncSettings" : { "properties": [ ] }, "lineItemSyncSettings": { "properties": [ ] }, "contactSyncSettings": { "properties": [ ] } }
The PUT
and GET
are completely symmetric. You can copy the response from the GET
and use it as the body of the PUT
.
HubSpot provides some additional property mappings to all Ecommerce Bridge settings. They are not editable, but there is an optional boolean query param showProvidedProperties
that can be used with both the PUT
and GET
endpoints to retrieve those as well. Note that doing so will prevent the responses from being symmetric.
DELETE /extensions/ecomm/v1/settings
Note that this cannot be undone. It is recommended that if you would like to disable sync messages from being applied using your property mappings that you disable your settings rather than deleting them.
Field name | Field type | Description |
---|---|---|
enabled |
boolean | Whether or not this application is "turned on" or actively syncing data. Setting this field to "false" enables you to build up your settings and only turn your sync on once you're comfortable that you have all the necessary data set up. When setting enabled to true the Settings API checks your property mappings to ensure that you've specified all properties required for the Ecommerce Bridge sync process, see Required Properties |
importOnInstall |
boolean | Whether or not to automatically kick off the import process once a user has installed your application. This field does not apply to settings for direct use of the API. |
productSyncSettings.properties |
Array of PropertyMappingobjects | Property mappings for the Product object. |
dealSyncSettings.properties |
Array of PropertyMappingobjects | Property mappings for the Deal object. |
lineItemSyncSettings.properties |
Array of PropertyMappingobjects | Property mappings for the Line Item object. |
contactSyncSettings.properties |
Array of PropertyMappingobjects | Property mappings for the Contact object. |
The PropertyMapping defines how we map properties defined in your system to properties defined in HubSpot.
Field name | Field type | Description |
---|---|---|
propertyName | String | The name of the property in your system. |
dataType | "STRING", "NUMBER", "DATETIME", "AVATAR_IMAGE" | The type of value we can expect for this property. "AVATAR_IMAGE" is expected to be a url for an image. Note that only one property mapping per object type can have the dataType "AVATAR_IMAGE", and currently this dataType is only available for use in productSyncSettings . |
targetHubspotProperty | String | The name of the property defined in HubSpot. This can be the name of a default HubSpot property or a custom property. |
Use the Sync Messages API to send HubSpot notifications of all creates, updates, and deletes of ecommerce objects.
An application should use the OAuth token for a specific customer to send these sync message requests, and a portal using the api directly should include its hapikey to send these sync message requests.
Up to 200 sync messages can be included in a single request.
Example request:
PUT /extensions/ecomm/v1/sync-messages/{objectType}
Where {objectType}
is one of: CONTACT
, DEAL
, PRODUCT
, or LINE_ITEM
With body:
[ { "integratorObjectId": "001", "action": "UPSERT", "changeOccurredTimestamp": 1507642200000, "propertyNameToValues" : { "my_name_field": "Example Product", "image": "https://url.to.image/image.png" } } ]
Note that this API allows you to send multiple sync messages for a single object-type. These messages can be for multiple objects of that object-type. For example you can send information about multiple Deals in the same call.
Field name | Field type | Description |
---|---|---|
integratorObjectId |
String, max length 100 characters, ascii-only | The ID, in your system, of the object that is being created/updated/deleted |
action |
UPSERT or DELETE |
The type of action this describes |
changeOccurredTimestamp |
long |
The epoch millisecond timestamp when the change that this message describes occurred Note: For object properties with existing values, values will only be updated if the |
propertyNameToValues |
Map | This is a map of your property names to the values for this object. These are the values that we will sync into corresponding HubSpot object The property values included should match the format that would be used for the mapped property. For example, when sending a datetime property for a contact property, the value should be a millisecond timestamp. |
Because sync messages are processed asynchronously, problems with processing are not surfaced at the time of submission. Instead, you can use the sync errors endpoint to retrieve all errors related to the processing of ecommerce data. Application developers should use their developer portal's hapikey and include the appId as a query param, and customer developers should use their portal's hapikey.
Path:
GET /extensions/ecomm/v1/sync-errors
Param name | Param type | Default value | Description |
---|---|---|---|
showResolvedErrors |
boolean | false | Whether errors that have been resolved should be returned |
limit |
integer, max 200 | 200 | The number of errors to be returned |
offset |
integer | 0 | The index of the first error to be returned |
Field name | Field type | Description |
---|---|---|
portalId |
integer | The portal in which an error occurred |
objectType |
String, Enum | The object of the sync message. One of CONTACT , DEAL , PRODUCT , or LINE_ITEM |
integratorObjectId |
String, max length 100 characters, ascii-only | The ID, in your system, of the sync message's object |
changeOccurredTimestamp |
long | The epoch millisecond timestamp from the sync message |
errorTimestamp |
long | The epoch millisecond timestamp when the error happened |
type |
String, Enum | Described below |
details |
String | More information about the error that happened |
status |
OPEN or RESOLVED |
Whether the errored object has since been synced correctly |
INACTIVE_PORTAL
- the portal to be modified by the sync message has been disabledNO_SYNC_SETTINGS
- there are no sync settings found for your portal or applicationSETTINGS_NOT_ENABLED
- the settings for your portal or application are not enabledNO_MAPPINGS_DEFINED
- the sync settings for your portal or application did not define property mappings for any properties in the sync messageMISSING_REQUIRED_PROPERTY
- an object to be created is missing a required propertyNO_PROPERTIES_DEFINED
- the portal does not have the mapped properties defined on itINVALID_ASSOCIATION_PROPERTY
- an association property does not correspond to any existing objectINVALID_DEAL_STAGE
- a deal update includes a deal stage that is not part of the ecommerce PipelineINVALID_EMAIL_ADDRESS
- a contact update includes an email address that is not validUNKNOWN_ERROR
- there was an unexpected problem trying to update the CRMImports only apply to and are only available for application development, not development on an individual portal.
The import process works as follows:
The customer initiates an import, and HubSpot sends your system the Import Initialization Webhook.
Your system sends all the relevent data for this customers store to HubSpot via the Import Pages Endpoint.
Your system uses the Import Page End Endpoint to indicate that you're done sending the import data for a particular object-type.
When HubSpot receives import page end requests for all object types: CONTACT
, DEAL
, PRODUCT
, and LINE_ITEMS
the import processing will apply all changes to HubSpot and the import will complete.
The import settings API is where you set the URI for the Import Initialization Webhook.
Use your developer account's hapikey to authenticate for these settings requests.
Settings Import Settings:
PUT /extensions/ecomm/v1/import-settings?appId={appId}
Example body:
{ "importTriggerUri": "https://example.com" }Retrieving Import Settings:
GET /extensions/ecomm/v1/import-settings?appId={appId}
{ "importTriggerUri": "https://example.com" }
When a user initiates an import, HubSpot will send the following request to the URI set via the Import Settings API.
POST /your-uri
Example request body:
{ "portalId": 2345, "importStartedAt": 1505590751000, "settingsToImport": [ { "settingsId": 51, "objectType": "CONTACT" }, { "settingsId": 52, "objectType": "DEAL" }, { "settingsId": 53, "objectType": "LINE_ITEM" }, { "settingsId": 54, "objectType": "PRODUCT" }, ] }
Example expected reponses:
{ "importCounts": [ { "settingsId": 51, "count": 1022 }, { "settingsId": 52, "count": 1044 }, { "settingsId": 53, "count": null }, { "settingsId": 54, "count": 349 } ] }
Property name | Property type | Description |
---|---|---|
portalId |
Number | The portalId of the customer requesting the import. This will be one of the customers that have installed your application. |
importStartedAt |
Number, epoch milliseconds | The time the customer requested the import. This timestamp identifies this specific import, and you'll use this value in the import pages endpoints. |
settingsToImport |
Array | This specifies which object types the customer has requested to import. Imports of a subset of object-types may be possible. |
settingsToImport.settingsId |
Number | An internal ID for the sync settings of a specific object-type. You don't need to worry about this idea except to generate the response for this request. |
settingsToImport.objectType |
String, one of CONTACT , DEAL , LINE_ITEM or PRODUCT |
The objectType this specific ID corresponds to. |
Property name | Property type | Description |
---|---|---|
importCounts |
Array | Objects that return the number of items to expect for each object type. The response must contain an element for each settingsToImport in the request. |
importCounts.settingsId |
Number | The corresponding settingsToImport.settingsId from the request. |
count |
Number or null |
The number of items that you're planning to import. This is for progress-estimation purposes. This can be an estimate. If this value cannot be reasonably estimated it can be set to null . |
This webhook request will contain a signature in the X-HubSpot-Signature
header. See the Webhooks documentation for instruction on how to validate this request based on the signature.
Once you've received an import initialization request you can send batches of items to HubSpot via this Import Paged Endpoint.
Use the OAuth token for a specific customer to send these import pages requests.
PUT /import-pages/{importStartedAt}/{objectType}/{pageNumber}
Url params:
importStartedAt
: The importStartedAt
timestamp from the import intialization request.objectType
: The object type this data corresponds to. (CONTACT
, DEAL
, LINE_ITEM
, or PRODUCT
)pageNumber
: A numeric page number that identifies this page of data. Must be unique within this import.Example request body:
[
{
"integratorObjectId": "001",
"propertyNameToValues" : {
"my_name_field": "Example Product",
"image": "https://url.to.image/image.png"
}
},
{
"integratorObjectId": "002",
"propertyNameToValues" : {
"my_name_field": "Example Product 2",
"image": "https://url.to.image/image-2.png"
}
}
]
The request body should consist of an array of Import Messages. You can specify up to 500 Import Messages per request.
Property name | Property type | Description |
---|---|---|
integratorObjectId |
String, max length 100 characters, ascii-only | The ID, in your system, of the object that is being created/updated/deleted. |
propertyNameToValues |
Map | This is a map of your property names to the values for this object. These are the values that we will sync into corresponding HubSpot object. |
Import Message are the same thing as Sync Messages, just without the action
property. (All import messages are UPSERT
s.)
One you're done sending all import-pages for a specific object type you need to send an import page end request. In order for an import to complete successfully, HubSpot must receive import-end notifications for each object type: Contacts, Deals, Line Items, and Products.
Use the OAuth token for a specific customer to send these import page end requests.
PUT /import-pages/{importStartedAt}/{objectType}/end
Url params:
importStartedAt
: The importStartedAt
timestamp from the import intialization request.objectType
: The object type this data corresponds to. (CONTACT
, DEAL
, LINE_ITEM
, or PRODUCT
)Example request body:
{
"pageCount": 12,
"itemCount": 5762
}
Request properties:
Property name | Property type | Description |
---|---|---|
pageCount |
Number | The number of pages you sent via the import pages endpoint. |
itemCount |
Number | The total number of items you sent via the import pages endpoint. |
This request will return a 400 error if the number of pages or items do not match what we actually received.