Overview for the Webhooks API, which allows you to subscribe to events happening in a HubSpot account with your integration installed.
crm.objects.contacts.read
scope.
POST
request to the /webhooks/v3/{appId}/subscriptions
endpoint, the response will include an error that will provide the name of the scope you’ll need to configure in the settings UI of your public app.POST
request to when events trigger.?hapikey
query parameter.
To view any webhook settings currently configured for an app, make a GET
request to webhooks/v3/{appId}/settings
.
You’ll need to include the app ID in the request, which you can find below the name of the app in your Apps dashboard, or on the Auth tab in your app’s settings.
The settings object contains the following fields:
Field | Description |
---|---|
webhookUrl | The URL that HubSpot will send webhook notifications to. This URL must be served over HTTPS. |
maxConcurrentRequests | The concurrency limit for the webhook URL. This value must be a number greater than five. |
PUT
request to webhooks/v3/{appId}/settings
and include the following fields in the request body:
Field | Description |
---|---|
targetUrl | The publicly available URL for HubSpot to call where event payloads will be delivered. |
throttling | An object with a single sub-property, maxConcurrentRequests , which allows you to set the maximum number of HTTP requests HubSpot will attempt to make to your app. This value must be specified as a number greater than five. |
associationChange
webhook subscriptions, the webhook will fire two events for both sides of the association.
contact.associationChange
will fire two events, representing contact 1 to contact 2
and contact 2 to contact 1
.contact.associationChange
and company.associationChange
, you will receive two events. These will represent contact 1 to company 1
and company 1 to contact 1
.eventType
field when creating subscriptions via API:
Subscription type | Scope required | Description |
---|---|---|
contact.creation | crm.objects.contacts.read | Get notified if any contact is created in a customer’s account. |
contact.deletion | crm.objects.contacts.read | Get notified if any contact is deleted in a customer’s account. |
contact.merge | crm.objects.contacts.read | Get notified if a contact is merged with another. |
contact.associationChange | crm.objects.contacts.read | Get notified if a contact has an association added or removed between itself and another supported webhook object (contact, company, deal, ticket, line item, or product). |
contact.restore | crm.objects.contacts.read | Get notified if a contact is restored from deletion. |
contact.privacyDeletion | crm.objects.contacts.read | Get notified if a contact is deleted for privacy compliance reasons. |
contact.propertyChange | crm.objects.contacts.read | Get notified if a specified property is changed for any contact in an account. |
company.creation | crm.objects.companies.read | Get notified if any company is created in a customer’s account. |
company.deletion | crm.objects.companies.read | Get notified if any company is deleted in a customer’s account. |
company.propertyChange | crm.objects.companies.read | Get notified if a specified property is changed for any company in a customer’s account. |
company.associationChange | crm.objects.companies.read | Get notified if a company has an association added or removed between itself and another supported webhook object (contact, company, deal, ticket, line item, or product). |
company.restore | crm.objects.companies.read | Get notified if a company is restored from deletion. |
company.merge | crm.objects.companies.read | Get notified if a company is merged with another. |
deal.creation | crm.objects.deals.read | Get notified if any deal is created in a customer’s account. |
deal.deletion | crm.objects.deals.read | Get notified if any deal is deleted in a customer’s account. |
deal.associationChange | crm.objects.deals.read | Get notified if a deal has an association added or removed between itself and another supported webhook object (contact, company, deal, ticket, line item, or product). |
deal.restore | crm.objects.deals.read | Get notified if a deal is restored from deletion. |
deal.merge | crm.objects.deals.read | Get notified if a deal is merged with another. |
deal.propertyChange | crm.objects.deals.read | Get notified if a specified property is changed for any deal in a customer’s account. |
ticket.creation | tickets | Get notified if a ticket is created in a customer’s account. |
ticket.deletion | tickets | Get notified if any ticket is deleted in a customer’s account. |
ticket.propertyChange | tickets | Get notified if a specified property is changed for any ticket in a customer’s account. |
ticket.associationChange | tickets | Get notified if a ticket has an association added or removed between itself and another supported webhook object (contact, company, deal, ticket, line item, or product). |
ticket.restore | tickets | Get notified if a ticket is restored from deletion. |
ticket.merge | tickets | Get notified if a ticket is merged with another. |
product.creation | e-commerce | Get notified if any product is created in a customer’s account. |
product.deletion | e-commerce | Get notified if any product is deleted in a customer’s account. |
product.restore | e-commerce | Get notified if a product is restored from deletion. |
product.merge | e-commerce | Get notified if a product is merged with another. |
product.propertyChange | e-commerce | Get notified if a specified product is changed for any product in a customer’s account. |
line_item.creation | crm.objects.line_items.read | Get notified if any line item is created in a customer’s account. |
line_item.deletion | crm.objects.line_items.read | Get notified if any line item is deleted in a customer’s account. |
line_item.associationChange | crm.objects.line_items.read | Get notified if a line item has an association added or removed between itself and another supported webhook object (contact, company, deal, ticket, line item, or product). |
line_item.restore | crm.objects.line_items.read | Get notified if a line item is restored from deletion. |
line_item.merge | crm.objects.line_items.read | Get notified if a line item is merged with another. |
line_item.propertyChange | crm.objects.line_items.read | Get notified if a specified property is changed for any line item in a customer’s account. |
Subscription type | Scope | Description |
---|---|---|
conversation.creation | conversations.read | Get notified if a new thread is created in an account. |
conversation.deletion | Get notified if a thread is archived or soft-deleted in an account. | |
conversation.privacyDeletion | Get notified if a thread is permanently deleted in an account. | |
conversation.propertyChange | Get notified if a property on a thread has been changed. | |
conversation.newMessage | Get notified if a new message on a thread has been received. |
num_unique_conversion_events
hs_lastmodifieddate
assignedTo
: the conversation thread has been reassigned or unassigned. If the thread was reassigned, the propertyValue
will be an actor ID in the webhooks payload; if unassigned, it will be empty.status
: the status of the conversation thread has changed. In the webhooks payload, the propertyValue
will either be OPEN
or CLOSED
.isArchived
: the conversation thread has been restored. The propertyValue
in the webhooks payload will always be FALSE
.Field | Description |
---|---|
id | A number representing the unique ID of a subscription. |
createdAt | The time in milliseconds when this subscription was created. |
createdBy | The user ID associated with the user who created the subscription. |
active | This indicates whether or not the subscription is turned on and actively triggering notifications. The value can be true or false . |
eventType | The type of subscription. The table at the start of this section includes the available subscription types. |
propertyName | The name of the property the subscription will listen for changes to. This is only needed for property change subscription types. |
GET
request to webhooks/v3/{appId}/subscriptions
.
The response will be an array of objects representing your subscriptions. Each object will include information on the subscription like the ID, create date, type, and whether or not it’s currently active. Here’s what an example response would look like:
POST
request to webhooks/v3/{appId}/subscriptions
.
In the request body, you can include the following fields:
Field | Description |
---|---|
eventType | The type of subscription. |
propertyName | The name of the property the subscription will listen for changes to. This is only needed for property change subscription types. |
active | This indicates whether or not the subscription is turned on and actively triggering notifications. The value can be true or false . |
id
, createdAt
, or createdBy
, as those fields are set automatically.
For example, your request body may appear similar to the following:
eventType
must be a valid subscription type as defined in the above section and the propertyName
must be a valid property name. If a customer has no property defined that matches this value, then this subscription will not result in any notifications.
PUT
request to webhooks/v3/{appId}/subscriptions/{subscriptionId}
.
In the request body, include the following:
Field | Description |
---|---|
active | This indicates whether or not the subscription is turned on and actively triggering notifications. The value can be true or false . |
DELETE
request to webhooks/v3/{appId}/subscriptions/{subscriptionId}
.
POST
requests containing JSON formatted data from HubSpot.
To ensure that the requests you’re getting at your webhook endpoint are actually coming from HubSpot, HubSpot populates a X-HubSpot-Signature
header with a SHA-256 hash built using the client secret of your app combined with details of the request. Learn more about validating request signatures.
Use the tables below to view details about fields that may be contained in the payload.
Field | Description |
---|---|
objectId | The ID of the object that was created, changed, or deleted. For contacts this is the contact ID; for companies, the company ID; for deals, the deal ID; and for conversations the thread ID. |
propertyName | This is only sent for property change subscriptions and is the name of the property that was changed. |
propertyValue | This is only sent for property change subscriptions and represents the new value set for the property that triggered the notification. |
changeSource | The source of the change. This can be any of the change sources that appear in contact property histories. |
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 a notification about the event. |
portalId | The customer’s HubSpot account ID where the event occurred. |
appId | The ID of your application. This is used 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 subscription this notification is for. Review the list of supported subscription types in the webhooks subscription section above. |
attemptNumber | Starting at 0, which number attempt this is to notify your service of this event. If your service times-out or throws an error as describe in the Retries section below, HubSpot will attempt to send the notification again. |
messageId | This is only sent when a webhook is listening for new messages to a thread. It is the ID of the new message. |
messageType | This is only sent when a webhook is listening for new messages to a thread. It represents the type of message you’re sending. This value can either be MESSAGE or COMMENT . |
Field | Description |
---|---|
primaryObjectId | The ID of the merge winner, which is the record that remains after the merge. In the HubSpot merge UI, this is the record on the right. |
mergedObjectIds | An array of IDs that represent the records that are merged into the merge winner. In the HubSpot merge UI, this is the record on the left. |
newObjectId | The ID of the record that is created as a result of the merge. This is separate from primaryObjectId because in some cases a new record is created as a result of the merge. |
numberOfPropertiesMoved | An integer representing how many properties were transferred during the merge. |
Field | Description |
---|---|
associationType | The type of association, which will be one of the following:
|
fromObjectId | The ID of the record that the association change was made from. |
toObjectId | The ID of the secondary record in the association event. |
associationRemoved | A boolean that represents the following:
|
isPrimaryAssociation | A boolean that represents the following:
|
occurredAt
property for each notification to determine when the event that triggered the notification occurred.
HubSpot also does not guarantee that you’ll only get a single notification for an event. Though this should be rare, it is possible that HubSpot will send you the same notification multiple times.
GET
and POST
endpoints available for HubSpot to send data to each time an event is triggered. If you’re still developing your backend service, you can run a quick test with a dummy webhook URL using a third party service such as https://webhook.site, but make sure you don’t send any proprietary, confidential, or sensitive data of any kind from your HubSpot account.
contact.privacyDeletion
subscription type to receive webhook notifications when a user performs a privacy compliant contact deletion.
Privacy deletion notifications have some special behavior:
X-HubSpot-Signature
header with a SHA-256 hash of the concatenation of the app-secret for your application and the request body HubSpot is 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, the request came from someone else who knows your application secret. It’s important to keep this value secret.
If these values do not match, then this request may have been tampered with in-transit or someone may be spoofing webhook notifications to your endpoint.
Learn more about validating signature requests.
POST
requests that HubSpot sends to your service via your webhook subscriptions will not count against your app’s API rate limits.
You can create a maximum of 1000 subscriptions per application. If you attempt to create more you will receive a 400 bad request in return with the following body: