CRM Extensions API

CRM Extensions allow an integration to surface its own data in a card in the CRM sidebar for contacts, companies, or deals.  When a contact, company, or deal record is loaded by a HubSpot user, HubSpot makes an outbound request, retrieves information for that record, then displays in on a card in the sidebar. In addition to displaying data, integrations will also be able to specify actions that a user will be able to take, including opening a modal window, allowing your integration to appear seamlessly inside the HubSpot CRM.

Here's an example of what that looks like:

sidebar example

The whole card is defined by an object type the integrator can specify. Individual items within the card are sales objects.

Object Types are created under the applications in an integrators developer account. When the user installs an application, HubSpot starts sending data fetch requests for object types associated with that application.

The data flow for how Sales Objects show up on the CRM looks like this:

Sales Object data flow diagram

When a user visits a contact, company, or deal details page in the CRM, HubSpot will send a data fetch request to the integrator. The integrator will respond to this request with the Sales Objects associated to the current CRM object.

Object Type API

Object Types show the integrator's intent to provide some objects associated with data in the CRM. Creating an Object Type is the first step in using CRM Extensions.

Object Type Fields

This section describes the different fields on the Object Type.

  • applicationId: The ID of the application that should own this object type.
  • baseUris: A list of URIs. When you define actions, the URIs for these actions must be under one of these URIs.
  • dataFetchUri: The URI the CRM will call to fetch Sales Objects for a given Contact, Company or Deal.
  • title: The title of this object. This will be displayed as the title of the CRM sidebar card.
  • propertyDefinitions: The common properties that these objects will have, in the order they should appear on the sidebar card. See Property Types for more info.
  • associatedHubSpotObjectTypes: A set of CONTACT, COMPANY, or DEAL. This determines where on the CRM this Object Type will appear -- contact, company, or deal details pages.
  • associatedHubSpotObjectTypeProperties: HubSpot properties to send in the data fetch request, by CRM object type.

Example object type:

{
  "applicationId": 767676,
  "baseUris": [
    "https://example.com/actions"
  ],
  "dataFetchUri": "https://example.com/demo-tickets",
  "title": "DemoTickets",
  "propertyDefinitions": [
    {
      "name": "ticket_type",
      "label": "Ticket type",
      "dataType": "STRING"
    },
    {
      "options": [
        {
          "type": "SUCCESS",
          "label": "In Progress",
          "name": "inprogress"
        },
        {
          "type": "DEFAULT",
          "label": "Resolved",
          "name": "resolved"
        }
      ],
      "name": "status",
      "label": "Status",
      "dataType": "STATUS"
    },
    {
      "name": "priority",
      "label": "Priority",
      "dataType": "STRING"
    },
    {
      "name": "project",
      "label": "Project",
      "dataType": "STRING"
    }
  ],
  "associatedHubSpotObjectTypes": [
    "COMPANY"
  ],
  "associatedHubSpotObjectTypeProperties": {
    "COMPANY": [
      "domain"
    ]
  }
}

The following shows how the different Object Type properties show up to the user:

object type annoations

Managing object types through the API

See the specific docs for managing object types through the API:

Managing object types through the developer tools

In addition to managing the object types through the API, you can also create and manage object types from your developer tools. When viewing the settings for your app, you can create an object type for your app from the CRM extension API tab.

 crm_extensions_tab.png

Once you create an object type, you can also mange its settings by clicking on the name of the object type.

type_settings.png

Data Fetch Request

The data fetch request is a request that HubSpot makes to the integrator when a HubSpot user needs sales object data. Currently, this request happens each time a user visits a specific contact, company, or deal in the CRM.

HubSpot will make a separate request for each object type. HubSpot will send the request to the dataFetchUri specified on the object type.

The response to this data fetch request should contain information to display to the user at that time. It can contain up to 5 sales objects. If more sales objects are available for this specific CRM object, the integrator can provide a link that the user can follow to see all related sales objects.

Example Request

GET https://example.com/demo-tickets?userId=12345&userEmail=testuser@example.com&associatedObjectId=78912&associatedObjectType=COMPANY&portalId=9999999&domain=testcompany.com

With a header:

X-HubSpot-Signature: <some base64 string>

The query parameters provided in this request are:

  • userId: The numeric userId of the customer requesting data.
  • userEmail: The user address, in HubSpot, of the user requesting data.
  • associatedObjectId: Either the companyId, dealId, or contact vid for the current object, depending on the associatedObjectType.
  • associatedObjectType: The type of object the user is requesting data about (CONTACT, COMPANY, or DEAL). This will be one of the associatedHubSpotObjectTypes provided for this object type.
  • And values for any of the requested associatedHubSpotObjectTypeProperties. If one of the request properties is not defined for the current object, it will not be listed in the query string. In the example above, the company property domain is included

The X-HubSpot-Signature header provides a way for the integrator to verify this request came from HubSpot. See Request Signatures for details.

Example Response

This is an example response the integrator should provide to the above request.

{
  "results": [
    {
      "objectId": 245,
      "title": "API-22: APIs working too fast",
      "link": "http://example.com/1",
      "created": "2016-09-15",
      "priority": "HIGH",
      "project": "API",
      "reported_by": "msmith@hubspot.com",
      "description": "Customer reported that the APIs are just running too fast. This is causing a problem in that they're so happy.",
      "reporter_type": "Account Manager",
      "status": "In Progress",
      "ticket_type": "Bug",
      "updated": "2016-09-28",
      "actions": [
        {
          "type": "IFRAME",
          "width": 890,
          "height": 748,
          "uri": "https://example.com/edit-iframe-contents",
          "label": "Edit",
          "associatedObjectProperties": []
        },
        {
          "type": "IFRAME",
          "width": 890,
          "height": 748,
          "uri": "https://example.com/reassign-iframe-contents",
          "label": "Reassign",
          "associatedObjectProperties": []
        },
        {
          "type": "ACTION_HOOK",
          "httpMethod": "PUT",
          "associatedObjectProperties": [],
          "uri": "https://example.com/tickets/245/resolve",
          "label": "Resolve"
        },
        {
          "type": "CONFIRMATION_ACTION_HOOK",
          "confirmationMessage": "Are you sure you want to delete this ticket?",
          "confirmButtonText": "Yes",
          "cancelButtonText": "No",
          "httpMethod": "DELETE",
          "associatedObjectProperties": [
            "protected_account"
          ],
          "uri": "https://example.com/tickets/245",
          "label": "Delete"
        }
      ],
    },
    {
      "objectId": 988,
      "title": "API-54: Question about bulk APIs",
      "link": "http://example.com/2",
      "created": "2016-08-04",
      "priority": "HIGH",
        "project": "API",
        "reported_by": "ksmith@hubspot.com",
        "description": "Customer is not able to find documentation about our bulk Contacts APIs.",
        "reporter_type": "Support Rep",
        "status": "Resolved",
        "ticket_type": "Bug",
        "updated": "2016-09-23",
        "properties": [
          {
            "label": "Resolved by",
            "dataType": "EMAIL",
            "value": "ijones@hubspot.com"
          },
          {
            "label": "Resolution type",
            "dataType": "STRING",
            "value": "Referred to documentation"
          },
          {
            "label": "Resolution impact",
            "dataType": "CURRENCY",
            "value": "94.34",
            "currencyCode": "GBP"
          }
        ],
        "actions": [
          {
            "type": "IFRAME",
            "width": 890,
            "height": 748,
            "uri": "https://example.com/edit-iframe-contents",
            "label": "Edit"
          },
          {
            "type": "CONFIRMATION_ACTION_HOOK",
            "confirmationMessage": "Are you sure you want to delete this ticket?",
            "confirmButtonText": "Yes",
            "cancelButtonText": "No",
            "httpMethod": "DELETE",
            "associatedObjectProperties": [
              "protected_account"
            ],
            "uri": "https://example.com/tickets/245",
            "label": "Delete"
          }
        ]
      }
    ],
    "settingsAction": {
      "type": "IFRAME",
      "width": 890,
      "height": 748,
      "uri": "https://example.com/settings-iframe-contents",
      "label": "Settings"
    },
    "primaryAction": {
      "type": "IFRAME",
      "width": 890,
      "height": 748,
      "uri": "https://example.com/create-iframe-contents",
      "label": "Create Ticket"
    }
  }

Definitions for the fields in the response body:

  • results : A list of up to 5 valid Sales Objects. See the following section, Sales Object Properties for details.
  • totalCount : The total number of sales object available, if there are more than 5 Sales Objects related to the requested CRM object. This property is optional.
  • allItemsLink: A URI that shows all sales objects associated to the requested CRM object, if there are more than 5. This property is optional.
  • itemLabel: The label to be used in the "see more" link. (e.g. "See more tickets") If not provided, this falls-back to the object type's Title. This property is optional.
  • settingsAction: An IFrame Action that gives users the ability to update settings for this integration. See Action Types for details on specifying Actions. This property is optional.
  • primaryAction: The primary action for an object type. This is typically a "creation" action. See Action Types for details on specifying Actions. This property is optional.
  • secondaryActions: A list of actions to display on the card level. See Action Types for details on specifying Actions. This property is optional.

data fetch annotations

Sales Object Properties 

JSON for an example Sales Object:

    {
      "objectId": 988,
      "title": "API-54: Question about bulk APIs",
      "link": "http://example.com/2",
      "created": "2016-08-04",
      "priority": "HIGH",
      "project": "API",
      "reported_by": "ksmith@hubspot.com",
      "description": "Customer is not able to find documentation about our bulk Contacts APIs.",
      "reporter_type": "Support Rep",
      "status": "Resolved",
      "ticket_type": "Bug",
      "updated": "2016-09-23",
      "properties": [
        {
          "label": "Resolved by",
          "dataType": "EMAIL",
          "value": "ijones@hubspot.com"
        },
        {
          "label": "Resolution type",
          "dataType": "STRING",
          "value": "Referred to documentation"
        },
        {
          "label": "Resolution impact",
          "dataType": "CURRENCY",
          "value": "94.34",
          "currencyCode": "GBP"
        }
      ],
      "actions": [
        {
          "type": "IFRAME",
          "width": 890,
          "height": 748,
          "uri": "https://tools.hubteam.com/integrations-iframe-test-app",
          "label": "Edit"
        },
        {
          "type": "CONFIRMATION_ACTION_HOOK",
          "confirmationMessage": "Are you sure you want to delete this ticket?",
          "confirmButtonText": "Yes",
          "cancelButtonText": "No",
          "httpMethod": "DELETE",
          "associatedObjectProperties": [
            "protected_account"
          ],
          "uri": "https://api.hubapi.com/linked-sales-objects-test-application/v1/actions/demo-ticket/988",
          "label": "Delete"
        }
      ]
    }

Properties:

  • objectId: A unique ID for this object.
  • title: The title of this object.
  • link: The URI the user can follow to get more details about this object. This property is optional.
  • properties: A list of custom properties that are not defined in the object type. You can use this list to display properties unique to this specific object. These properties will be shown after the properties defined in the object-type in the order they're provided. This property is optional.
  • actions: A list of actions that are available to take on this object. See Action Types for details on specifying Actions. This property is optional.

In addition to the above properties, the integrator can provide values for the properties defined on the object-type. In the above example the created JSON property:

"created":"2016-08-04"

Is providing a value for this object for the created property defined on the Object Type.

sales object annotations

Handling Action Hooks 

When a user clicks on an action that is defined as an Action Hook, HubSpot will send a request using the URI and HTTP method specified in the action definition.

Example Request

DELETE https://example.com/tickets/245?userId=12345&userEmail=testuser@example.com&associatedObjectId=78912&associatedObjectType=COMPANY&portalId=9999999&domain=testcompany.com

With a header:

X-HubSpot-Signature: <some base64 string>

The query parameters provided in this request are:

  • userId: The numeric userId of the customer requesting data.
  • userEmail: The user address, in HubSpot, of the user requesting data.
  • associatedObjectId: Either the companyId, dealId, or contact vid for the current object, depending on the associatedObjectType.
  • associatedObjectType: The type of object the user is requesting data about (CONTACT, COMPANY, or DEAL).
  • portalId: The portal ID (also called Hub ID) of the customer that is requesting data. This will be a customer that has installed your integration.
  • And values for any of the requested associatedObjectProperties. If one of the request properties is not defined for the current object, it will not be listed in the query string. In the above example, the company property domain is included.

The X-HubSpot-Signature header provides a way for the integrator to verify this request came from HubSpot. See Request Signatures for details.

Example Response

{
  "message": "Successfully deleted object"
}

HubSpot will attempt to parse responses to action hooks as JSON and look for a message property. HubSpot will display this message to the user on either success or failure.

Response status code of 2xx will show a success message and status codes of 4xx or 5xx will show an error message.

Action Types

The following sections provide details about each type of Action that can be specified.

IFrame Actions

When a user clicks an IFrame action, a modal dialog will open containing an iframe pointing at the provided URL.

Example IFrame action:

{
  "type": "IFRAME",
  "width": 890,
  "height": 748,
  "uri": "https://example.com/iframe-contents",
  "label": "Edit",
  "associatedObjectProperties": [
    "some_crm_property"
  ]
}
  • type: Should be IFRAME to indicate that this is an IFrame action.
  • width, height: The dimensions that the iframe should be.
  • uri: The URI to open inside the iframe.
  • label: The label to display in the action drop-down.
  • associatedObjectProperties: A list of properties on the associated contact, company, or deal. The values of the properties for the current object will be appended to the uri as query parameters when opening the iframe.

Signaling for the modal to close

When the user is done completing an action inside the iframe the modal dialog should close, returning the user back to the CRM screen the started from. To close the dialog model, the integrator can use window.postMessage to signal to the CRM that the user is done. The following messages are accepted.

  • {"action": "DONE"} - The user has successfully completed the action.
  • {"action": "CANCEL"} - The user has canceled the action.

Action Hook Actions

Action hook actions send a server-side request to the integrator. The only UI a users sees for this action is a success or error message. This type of action is useful for simple operations that require no further input from the user.

Example action hook action definition:

{
  "type": "ACTION_HOOK",
  "httpMethod": "POST",
  "uri": "https://example.com/action-hook",
  "label": "Example action",
  "associatedObjectProperties": [
    "some_crm_property"
  ]
}
  • type: Should be ACTION_HOOK to indicate that this is an action hook action.
  • httpMethod: The HTTP method to use when making the request. This can be GET, POST, PUT, DELETE, or PATCH.
  • uri: The URI of the request to make.
  • label: The label to display in the action drop-down.
  • associatedObjectProperties: A list of properties on the associated contact, company, or deal. If httpMethod is GET or DELETE than these property values will be appended to the URI of the request as query parameters. Otherwise they will be sent as a JSON request body.

See Handling Action Hooks for more details on how to implement the action endpoint.

Confirmation Actions

Confirmation actions behave the same as action hooks except that a confirmation dialog is shown to the user before running the server-side request.

{
  "type": "CONFIRMATION_ACTION_HOOK",
  "httpMethod": "POST",
  "uri": "https://example.com/action-hook",
  "label": "Example action",
  "associatedObjectProperties": [
    "some_crm_property"
  ],
  "confirmationMessage": "Are you sure you want to run example action?",
  "confirmButtonText": "Yes",
  "cancelButtonText": "No"
}
  • type: Should be CONFIRMATION_ACTION_HOOK to indicate that this is a confirmation action hook action.
  • httpMethod: The HTTP method to use when making the request. This can be GET, POST, PUT, DELETE, or PATCH.
  • uri: The URI of the request to make.
  • label: The label to display in the action drop-down.
  • associatedObjectProperties: A list of properties on the associated contact, company, or deal. If httpMethod is GET or DELETE than these property values will be appended to the URI of the request as query parameters. Otherwise they will be sent as a JSON request body.
  • confirmationMessage: The message to display to the user in the confirmation dialog.
  • confirmButtonText: The text for the "OK" button. This is optional, the button text will default to "OK".
  • cancelButtonText: Text text for the "Cancel" button. This is optional, the button text will default to "Cancel".

See Handling Action Hooks for more details on how to implement the action endpoint.

Request Signatures 

To ensure that the requests you're getting at your data fetch URIs and action hook URIs are actually coming from HubSpot, we populate a X-HubSpot-Signature header with a SHA-256 hash of the concatenation of the app-secret for your application and the request body we're sending.

To verify this signature, perform the following steps:

  1. Create a string that concatenates together the following: App secret + http method + URI + request body (if present)
  2. Create a SHA-256 hash of the resulting string.
  3. Compare the hash value to the signature. If they're equal than this request has passed validation. If these values do not match, than this request may have been tampered with in-transit or someone may be spoofing requests to your endpoint.

Docs for this section or API