Supporting imports with the Ecommerce Bridge

Note: Imports are only supported for apps that use OAuth. Imports cannot be used with custom integrations using an API key.

Imports give users of your application a solid user experience when first connecting your app.

While it is possible to use normal sync messages with the changeOccurredTimestamp value to import historical data, supporting imports allows your customers to make the choice for whether to import that historical data or not. Using imports also allows your users to see the progress of that importing inside of HubSpot in their ecommerce settings.

Additionally, the import process will automatically process imported objects in the optimized order, which can help speed up the processing of the imported objects, allowing users to see their historical data in HubSpot faster.

In order to support imports, you'll need to set the webhookUri for the Ecommerce Bridge settings for your app. Once that webhook URI is set, users will see the import dialog for any stores created by your app (including the default store). When a user clicks the button to start the import, we'll send a webhook to that URI.

How do users initiate an import?

After a user connects you app to HubSpot, the user will see a "Continue importing" button when viewing the details for the store in their Ecommerce settings. They'll also have the option to view the details for a different store, if they have multiple stores set up.

When a user clicks the Continue importing button, we'll send the import webhook to the webhookUri in your app's Ecommerce Bridge settings.

While the import is in progress, users will be able to see the progress in the store details. The progress bar will automatically be generated based on the number of records that you sent in the response for the initial import webhook, and the number of records that have been imported so far.

When you are finished importing objects and have signaled the end of the import, we'll show the number of imported objects. There will be an alert message if HubSpot is still creating objects from the import.

Import API reference

Setting up the import trigger URI.

In order to support imports, the first thing you'll need to do is set up the webhookUri in your apps Ecommerce Bridge settings. This is done using the following endpoint:

PUT https://api.hubapi.com/extensions/ecomm/v2/settings?appId={yourAppId}&hapikey={yourDeveloperAccountHapikey}

{
  "enabled": true,
  "webhookUri": "https://api.exampleapp.com/ecomm-import-trigger/",
  "mappings": {
    "CONTACT": { ... },
    "DEAL": { ... },
    "PRODUCT": { ... },
    "LINE_ITEM": { ... }
  }
}

// Returns the current settings on success:
{
  "enabled": true,
  "webhookUri": "https://api.exampleapp.com/ecomm-import-trigger/",
  "mappings": {
    "CONTACT": { ... },
    "DEAL": { ... },
    "PRODUCT": { ... },
    "LINE_ITEM": { ... }
  }
}

Handling the import webhook

Once that webhookUri is set up, users will have the Continue importing button when viewing the details for stores set up by your app. When a user clicks that button, we'll send the following POST request to your URI:

{
  "portalId": 1234567,
  "storeId": "store-to-import-id",
  "importStartedAt": 1552678940201,
  "settingsToImport": [
    {
      "settingsId": 1,
      "objectType": "PRODUCT"
    },
    {
      "settingsId": 2,
      "objectType": "CONTACT"
    },
    {
      "settingsId": 3,
      "objectType": "LINE_ITEM"
    },
    {
      "settingsId": 4,
      "objectType": "DEAL"
    }
  ]
}

Notes:

  • portalId is the Hub Id for the account that initiated the import.
  • storeId is the ID of the store that the import was initiated for.
  • importStartedAt is a millisecond timestamp for the time that the import was initiated. You can also treat this as the ID of the import.
  • settingsToImport will always be for the 4 object types - PRODUCT, CONTACT, LINE_ITEM, DEAL. They are included so you don’t have to assume the object types to import.

Your response to this webhook POST request must contain the count for each object type that you plan on importing. This is used to generate the progress bar that the user sees.

{
  "importCounts": [
    {
      "settingsId": 1,
      "count": 24
    },
    {
      "settingsId": 2,
      "count": 792
    },
    {
      "settingsId": 3,
      "count": 0
    },
    {
      "settingsId": 4,
      "count": 901
    }
  ]
}

Importing pages of records

Now that the import has been initiated, and we know how many records will be imported, you can start importing the data.

Note:

  • There is no time limit on completing the import. The status will show as in progress until you send the request to end the import for all objects.
  • Objects are processed in the following order, regardless of the order in which you send the objects:
    1. Contacts
    2. Deals
    3. Products
    4. Line items
  • Objects can be imported in any order. Objects will be processed after the end of the import is signaled, based on the processing order above: 
    • For example, if you import all contacts first, we'll start processing those contacts and creating (or updating) the contacts in HubSpot as soon as you signal the end of the contact import.
    • If you import deals first, we'll wait to process the records until the contacts are also imported and processed.

Importing records is done using the following endpoint:

POST extensions/ecomm/v2/imports/page

{
  "portalId": 1234567,
  "storeId": "store-to-import-id",
  "importStartedAt": 1552678940201,
  "objectType": "DEAL",
  "messages": [
    {
      "externalObjectId": "1234abc",
      "properties": {
        "amount": 24
      }
    },
    {
      "externalObjectId": "234fdc",
      "properties": {
        "amount": 24
      },
      "associations": {
        "CONTACT": [
          "2344a"
        ]
      }
    }
  ]
}

Notes:

  • Up to 500 import messages can be sent in a single request.
  • storeId must the ID of the store that the import was triggered for.
  • importStartedat must match the importStartedAt that was sent in the initial import tigger webhook

Signaling the end of the import for an object

Once you have imported all of the records for an object type, you will need to use the following endpoint to signal the end of the import:

POST extensions/ecomm/v2/imports/end

{
  "portalId": 1234567,
  "storeId": "store-to-import-id",
  "importStartedAt": 1552678940201,
  "objectType": "DEAL",
  "pageCount": 12,
  "itemCount": 1123
}

Note: You must signal the end of the import for each separate object type. The import will not be considered complete until this has been done for all 4 object types.

Once the end of the import has been signaled for all 4 object types, we'll show the import as complete! Note that we may still be processing the imported objects, depending on the number of imported objects and the order of the imported object types, See the screenshot above for an example of want the import would look like in this case.