Webhooks Overview

This Webhooks API allows you to subscribe to changes happening in the accounts of any HubSpot user that installs your integration. Using this webhook API requires:

  • That you set up a HubSpot app to use this API by subscribing to changes you want to be notified about, and by specifying a URL to send those notifications.  See the prerequisites documentation for more details about creating an app.
  • That you deploy an endpoint for that URL that can handle the webhook payloads that we specify in this documentation.

Webhooks are set up for a HubSpot app, not individual portals.  Any portals that install your app (by going through the OAuth flow) will be subscribed to any webhook subscriptions set up for the app.

Webhooks Setup

Webhook Subscriptions

Webhook Subscriptions tell HubSpot what a particular app would like to get notified about. We currently support the following subscription types:

  • Contact creations
  • Contact deletions
  • Contact property changes
  • Company creations
  • Company deletions
  • Company property changes
  • Deal creations
  • Deal deletions
  • Deal property changes

A couple things to keep note of when thinking about subscriptions:

  • For property change subscriptions, you will need to specify which property you want to be notified of. You can specify multiple property change subscriptions. If a customer's account doesn't have the property you specify in a subscription, you will not get any webhooks from that customer for that property.

  • Subscriptions apply to all customers that have installed your integration. This means that you only need to specify what subscriptions you need once. Once you've enabled a subscription for an application, it will automatically start getting webhooks for all customers that have installed your application, and you will automatically start getting webhooks from any new customers that install your integration going forward.

  • There is an up to five minute delay between when you create or change your subscriptions and when those changes take effect.

Managing Subscriptions via the UI

You can create webhook subscriptions via the developer app:

  1. In the developer app dashboard select the app that you'd like to send webhooks for.
  2. Select the "Webhook Subscriptions" nav item. From this screen, prompts will guide you through creating a new subscription.

Managing Subscriptions via the API

These endpoints allow you to programmatically create Subscriptions. There is nothing in these endpoints that you cannot do via the UI, and the UI is the preferred way to set up your app. You will need to use your Developer HAPIkey when making requests to these endpoints.

Subscription Fields

A subscription object has the following fields:

  • id - A number representing the unique ID of a subscription.
  • createdAt - When this subscription was created, this is a millisecond timestamp.
  • createdBy - The userId of the user that created this subscription.
  • enabled - Whether or not this subscription is currently active and triggering notifications.
  • subscriptionDetails - This describes what types of events this subscription is listening for
    • subscriptionType - A string representing what type of subscription this is--as defined in 'Subscription Types` below.
    • propertyName - Only needed for property-change types. The name of the property to listen for changes on. This can only be a single property name.
Subscription Types

The subscriptionType property can be one of the following values:

  • contact.creation - To get notified if any contact is created in a customer's portal.
  • contact.deletion - To get notified if any contact is deleted in a customer's portal.
  • contact.propertyChange - To get notified if a specified property is changed for any contact in a customer's portal.
  • company.creation - To get notified if any company is created in a customer's portal.
  • company.deletion - To get notified if any company is deleted in a customer's portal.
  • company.propertyChange - To get notified if a specified property is changed for any company in a customer's portal.
  • deal.creation - To get notified if any deal is created in a customer's portal.
  • deal.deletion - To get notified if any deal is deleted in a customer's portal.
  • deal.propertyChange - To get notified if a specified property is changed for any deal in a customer's portal.
Get Subscriptions

To retrieve the list of subscriptions:

GET https://api.hubapi.com/webhooks/v1/<<appId>>/subscriptions

The response will look like:

[
  {
    "id": 25,
    "createdAt": 1461704185,
    "createdBy": 529872,
    "subscriptionDetails": {
      "subscriptionType": "contact.propertyChange",
      "propertyName": "lifecyclestage"
    },
    "enabled": true
  },
  {
    "id": 59,
    "createdAt": 1462388498,
    "createdBy": 529872,
    "subscriptionDetails": {
      "subscriptionType": "company.creation"
    },
    "enabled": false
  },
  {
    "id": 108,
    "createdAt": 1463423132,
    "createdBy": 529872,
    "subscriptionDetails": {
      "subscriptionType": "deal.creation"
    },
    "enabled": true
  }
]
Create a New Subscription

To create new subscriptions:

POST https://api.hubapi.com/webhooks/v1/<<appId>>/subscriptions

With a request body like:

{
  "subscriptionDetails" : {
     "subscriptionType" : "company.propertyChange",
     "propertyName" : "companyname"
  },
  "enabled" : false
}

Where the fields in this request body match those defined in "Subscription Fields". However, with this endpoint you cannot specify id, createdAt, createdBy as those fields are set automatically. Note: subscriptions cannot be enabled until you set a Webhook URL for your app.  See the settings endpoint below for details on setting that URL.

Validation:

  • subscriptionType must be a valid Subscription Type as defined in the above section on "Subscription Types".
  • propertyName must be a valid property name. If a customer has no property defined that matches this value, than this subscription will not result in any notifications.
  • enabled must be true or false.
Update a Subscription

You can only update the enabled flag of a subscription. To do so you can use the following endpoint:

PUT https://api.hubapi.com/webhooks/v1/<<appId>>/subscriptions/<<subscriptionId>>

Request body:

{ "enabled" : false }
Delete a Subscription

To delete a subscription you can call the following endpoint:

DELETE https://api.hubapi.com/webhooks/v1/<<appId>>/subscriptions/<<subscriptionId>>

Webhook URL and Concurrency Limit

Before receiving any webhook notifications you need to specify a URL to send those notifications to. Optionally, you can also tune the number of concurrent requests your endpoint can handle.

Setting this concurrency limit helps us send you notifications as fast as possible without putting too much load on your API.

  • If you set this limit too low, you may find that notifications time out if there are too many notifications being sent to your API such that this limit is saturated for more than a second. This will result in delays before getting notifications.

  • If you set this limit too high, you may saturate the resources available to your endpoint which could result in slow responses, notification delays, or result in your endpoint becoming unresponsive.

The minimum concurrency limit we support is 5 concurrent requests. You must be able to support at least 5 concurrent requests against your endpoint in order to use the Webhooks API.

Managing via the UI

You can manage your URL and concurrency settings via the developer app:

  1. In the developer app dashboard select the app that you'd like to send webhooks for.
  2. Select the "Webhook Subscriptions" nav item. This screen provides a you can use to set the Webhooks URL and concurrency limit.

Managing via the API

These endpoints allow you to programmatically set webhook settings for an app. It is recommended that you use the UI to get your apps set up. You will need to use your Developer HAPIkey when making requests to these endpoints.

Settings Fields

The settings object has the following fields:

  • webhookUrl - The URL where we'll send webhook notifications.
  • maxConcurrentRequests - The concurrency limit for this URL, as discussed in "Webhook URL and Concurrency Limit"
Viewing Settings

The following endpoint access the webhook settings current set up for your application, if any:

GET https://api.hubapi.com/webhooks/v1/<<appId>>/settings

The result will look something like:

{
  "webhookUrl": "https://testing.com/webhook",
  "maxConcurrentRequests": 20
}
Updating Settings

To modify these settings you can use the following endpoint:

PUT https://api.hubapi.com/webhooks/v1/<<appId>>/settings

With a request body like:

{
  "webhookUrl": "https://testing.com/webhook-modified",
  "maxConcurrentRequests": 25
}

Validation:

  • webhookUrl must be a valid URL.
  • maxConcurrentRequests must be a number greater than 5.

Webhooks Payloads

The endpoint at the URL you specify in Webhooks Settings will receive requests like the following:

Method type: POST

Headers:

Content-Type: Application/Json
X-HubSpot-Signature: <<a hash of the app secret and request body>>

Example request body:

[
  {
    "objectId": 1246965,
    "propertyName": "lifecyclestage",
    "propertyValue": "subscriber",
    "changeSource": "ACADEMY",
    "eventId": 3816279340,
    "subscriptionId": 25,
    "portalId": 33,
    "appId": 1160452,
    "occurredAt": 1462216307945,
    "subscriptionType": "contact.propertyChange"
    "attemptNumber": 0,
  },
  {
    "objectId": 1246978,
    "changeSource": "IMPORT",
    "eventId": 3816279480,
    "subscriptionId": 22,
    "portalId": 33,
    "appId": 1160452,
    "occurredAt": 1462216307945,
    "subscriptionType": "contact.creation",
    "attemptNumber" : 0,
  },
  ...
]

Request fields:

  • objectId : The ID of the object that was created/changed/deleted. For contacts this is the vid; for companies, the companyId; and for deals the dealId.

  • propertyName : This is only sent when the notification is for a property change. This is the name of the property that was changed

  • propertyValue : This is only sent when the notification is for a property change. This is the new value that was set for this property that triggered this notification.

  • changeSource : The source of this change. Can be any of the change sources that you find on contact property histories.

  • eventId : The unique ID of the event that triggered this notification.

  • subscriptionId : The ID of the subscription that caused us to send you a notification of this event.

  • portalId : The customer's portalId that this event came from.

  • appId : The ID of your application. (In case you have multiple applications pointing to the same webhook URL.)

  • occurredAt : When this event occurred, as a millisecond timestamp.

  • subscriptionType : The type of event this notification is for. See the list of subscription types in the above section on "Subscription Types".

  • attemptNumber : Which attempt this is to notify your service of this event (starting at 0). If your service times-out or throws an error as described in "Retries" below, we will attempt to send the notification to your service again.

NOTE ON BATCHING: You will receive multiple notifications in a single request, as shown above. The batch size can vary over time as we tune the performance of this system, but we will keep the size within what is reasonable to send in a single request. We will send multiple notifications only when a lot of events have occurred within a short period of time. For example, if you've subscribed to new contacts and a customer imports a large number of contacts, we will send you the notifications for these imported contacts in batches and not one-per-request.

NOTE ON ORDER: We do not guarantee that you get these notifications in the order they occurred. Please use the occurredAt property for each notification to determine when the notification occurred.

NOTE ON UNIQUENESS: We do not guarantee that you will only get a single notification for an event. Though this should be rare, it is possible that we will send you the same notification multiple times.

Security

To ensure that the requests you're getting at your webhook endpoint 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, concatenate the app secret of your application and the un-parsed request body of the request you're handling, and get a SHA-256 hash of the result. Compare the resulting hash with the value of the X-HubSpot-Signature. If these values match, then this verifies that this request came from HubSpot. (Or someone else who knows your application secret. It's important to keep this value secret.) If these values do not match, than this request may have been tampered with in-transit or someone may be spoofing webhook notifications to your endpoint.

Retries

If your service has problems handling notifications at any time, we will attempt to re-send failed notifications up to 10 times.

We will retry in the following cases:

  • Connection Failed - If we cannot open an http connection to the provided webhook URL
  • Timeout - If your service takes longer than 1 second to send back a response to a batch of notifications
  • Error codes - If your service responds with an HTTP status code that is not one of: 400, 401, 403, 404, 405

Retries will occur with an exponential backoff based on the next attemptNumber. So the first retry will happen in 2 seconds, the second retry in 4 seconds, the third retry in 8 seconds, etc.

Batches and retries: When retrying, notifications will only be included in a batch for the initial attempt, and the first two retries. After that, notifications will be sent in their own batch of one, to prevent any issues with a specific notification in the batch from preventing a separate notification from completing successfully.

Docs for this section or API