The features described in this guide are in Early Access beta, separate from the CRM development tools to build UI extensions with React as frontend beta for private app UI extension development. 

Request access to the UI extensions for public apps beta

Working with webhooks (BETA)

Build webhooks into your public app to subscribe to events happening in the account that the app is installed in. 

In this guide, learn about:

Defining webhook subscriptions

Webhook subscriptions are defined in the webhooks.json file within a webhooks folder in the same directory as your app (e.g., src/app). You'll also need to update your public-app.json configuration file to reference that file.

public-app-webhooks-folder

The webhooks.json file contains fields for defining the webhook's settings and event subscriptions.

// Example webhooks.json { "settings": { "targetUrl": "https://example.com/webhook", "maxConcurrentRequests": 10 }, "subscriptions": { "crmObjects": [ { "subscriptionType": "object.propertyChange", "objectName": "contact", "propertyName": "firstname", "active": true }, { "subscriptionType": "object.creation", "objectName": "contact", "active": true } ], "legacyCrmObjects": [ { "subscriptionType": "contact.propertyChange", "propertyName": "lastname", "active": true }, { "subscriptionType": "contact.deletion", "active": true } ], "hubEvents": [ { "subscriptionType": "contact.privacyDeletion", "active": true } ] } }
Use this table to describe parameters / fields
ParameterTypeDescription
settings
Object

An object that specifies your webhook settings, including targetUrl and maxConcurrentRequests.

targetUrl
String

The URL that webhooks will be sent to. Learn more about the response payload sent with the POST request.

maxConcurrentRequests
String

The maximum number of concurrent requests that will be sent.

subscriptions
Object

An object that specifies the webhook subscriptions.

crmObjects
Array

An array containing event subscription definitions. This is the standard array to include, and should be used for all events in the new format (object.*). Classic webhook subscription types should instead be included in legacyCrmObjects and hubEvents arrays, depending on the event. See subscription types for more information.

subscriptionType
String

The type of event being subscribed to. Learn more about subscription types.

objectName
String

The CRM object being subscribed to.

propertyName
String

The property on the CRM object being subscribed to.

active
Boolean

Whether webhooks will be sent for this subscription.

legacyCrmObjects
Array

An array containing classic subscription types, such as contact.creation and deal.deletion. See the webhooks API guide for more information.

hubEvents
Array

An array containing the classic subscription types contact.privacyDeletion and conversation.*. See the webhooks API guide for more information.

Subscription types

Public apps built with projects use generic webhook subscription syntax, using the format object.* rather than specifying the object name in the subscription type (e.g., contact.*).

Subscription type Format
Creation object.creation
Deletion object.deletion
Merge object.merge
Restore object.restore
Property change object.propertyChange
Association change object.associationChange

To specify the type of CRM object you're subscribing to, include the objectName field in the subscription definition object using any of the supported objects in the table below. You'll need to include the object's corresponding scopes in your public-app.json file.

Supported objects
appointment fee quote_template
call feedback_submission task
cart goal_target tax
commerce_payment line_item ticket
communication listing partner_client
company meeting_event lead
contact note service
course order subscription
deal postal_mail invoice
discount product user
email quote partner_account
engagement    
// Example webhooks.json { "settings": { "targetUrl": "https://example.com/webhook", "maxConcurrentRequests": 10 }, "subscriptions": { "crmObjects": [ { "subscriptionType": "object.propertyChange", "objectName": "contact", "propertyName": "firstname", "active": true } ... ] } }

If you need to subscribe to classic subscription types, you can store them in the legacyCrmObjects and hubEvents arrays instead, depending on the type of subscription.

// Example webhooks.json { "settings": { "targetUrl": "https://example.com/webhook", "maxConcurrentRequests": 10 }, "subscriptions": { "legacyCrmObjects": [ { "subscriptionType": "contact.propertyChange", "propertyName": "lastname", "active": true }, { "subscriptionType": "contact.deletion", "active": true } ], "hubEvents": [ { "subscriptionType": "contact.privacyDeletion", "active": true } ] } }
Use this table to describe parameters / fields
ParameterTypeDescription
legacyCrmObjects
Array

An array containing classic subscription types (e.g., contact.propertyChange)

hubEvents
Array

An array that can contain the contact.privacyDeletion and conversation.* classic subscription types.

Response payloads

When an event that the app is subscribed to occurs, the targetUrl you specify in webhooks.json will receive a POST request containing JSON formatted data from HubSpot. All events will include the same base set of fields, with other fields being added depending on the event type. Learn more about parsing webhook payloads for specific event types..

Below is an example payload for propertyChange event. This type of event contains all generic fields, plus the propertyName and propertyValue fields to show which property changed and the new value.

// Example webhooks response payload [ { "appId": 3715530, "eventId": 100, "subscriptionId": 2764026, "portalId": 123456, "occurredAt": 1723651850844, "subscriptionType": "object.propertyChange", "attemptNumber": 0, "objectId": 987654, "changeSource": "CRM", "objectTypeId": "0-1", "propertyName": "firstname", "propertyValue": "sample-value", "isSensitive": false } ]
Use this table to describe parameters / fields
FieldDescription
appId

The ID of your public app. This can be helpful if you have multiple applications pointing to the same webhook URL.

eventId

The ID of the event that triggered this notification. This value is not guaranteed to be unique.

subscriptionId

The ID of the subscription that triggered the event.

portalId

The ID of the HubSpot account where the event occurred. 

occurredAt

When the event occurred as a unix timestamp (in milliseconds).

subscriptionType

The webhook subscription type. Can be one of the following:

  • object.creation
  • object.deletion
  • object.merge
  • object.restore
  • object.propertyChange
  • object.associationChange
attemptNumber

Starting at 0, which number attempt this is to notify your service of this event.

objectId

The ID of the object that was created, changed, or deleted. For example, for a contact-related event, objectId would be the contact's ID.

changeSource

The source of the change. This can be any of the change sources that appear in contact property histories.

objectTypeId

The type of object that triggered the event. See the full list of object type IDs for more information.

propertyName

The name of the property that was updated (for object.propertyChange events only).

propertyValue

The new property value that resulted from the change (for object.propertyChange events only).

isSensitive

Will be true if the property is a sensitive data property.

sourceId

The ID of the source that triggered the event (e.g., a user ID if it was a user that updated the property data).

The object.associationChange subscription will trigger for all associations, including custom association labels. Association change events will also trigger on both incoming and outgoing association changes. This means that an object.associationChange event defined for an objectName of contact will not only trigger on a CONTACT_TO_DEAL association change, but also on a DEAL_TO_CONTACT association change.

// Example webhooks response payload [ { "eventId": 668521389, "subscriptionId": 621550, "portalId": 123456, "appId": 3715530, "occurredAt": 1715708228603, "subscriptionType": "object.associationChange", "attemptNumber": 0, "changeSource": "USER", "associationType": "CONTACT_TO_DEAL", "associationCategory": "HUBSPOT_DEFINED", "associationTypeId": 4, "fromObjectId": 3788, "fromObjectTypeId": "0-3", "toObjectId": 4658499728, "toObjectTypeId": "0-1", "associationRemoved": true, "isPrimaryAssociation": false, "sourceId": "userId:864745280" }, { "eventId": 2975980077, "subscriptionId": 621550, "portalId": 885814039, "appId": 5553555, "occurredAt": 1715708228603, "subscriptionType": "object.associationChange", "attemptNumber": 0, "changeSource": "USER", "associationType": "DEAL_TO_CONTACT", "associationCategory": "HUBSPOT_DEFINED", "associationTypeId": 3, "fromObjectId": 4658499728, "fromObjectTypeId": "0-3", "toObjectId": 3788, "toObjectTypeId": "0-1", "associationRemoved": true, "isPrimaryAssociation": false, "sourceId": "userId:864745280" } ]

View webhook subscriptions in HubSpot

On the app settings page in HubSpot, you can view a list of each event subscription for each subscription in the app's webhooks.json file.

To view an app's webhook subscriptions in HubSpot:

  • In the left sidebar of your developer account, navigate to Apps.
    developer-account-app-navigation
  • Click the name of the app.
  • In the left sidebar, under Features, click Webhooks.
    public-app-webhooks
  • Under Event subscriptions, you can view each of the app's webhook subscriptions.
  • To view more information about a subscription, including number of times triggered and number of errors, click the name of the subscription.
    • Click the numbers in the Total count and Errors columns to navigate to the webhooks monitoring tab.
    • Hover over a subscription type then click Details to open the details panel on the right. This panel includes a sample event response payload and a testing feature.
      public-app-webhooks-subscription-details

Was this article helpful?
This form is used for documentation feedback only. Learn how to get help with HubSpot.