Webhooks
Webhook integration

HubSpot Webhooks: Send CRM Events to Sazabi

By Sazabi Team

Webhook facts checked on the platform’s docs on Nov 8, 2026.

HubSpot webhooks push CRM changes to a URL you control: a contact is created, a deal moves to a new stage, a company is deleted. They belong to an app, not to a single workflow, so setup differs a little from most platforms here.

What HubSpot sends

You subscribe to subscription types, each naming an object and a change. The guide lists types such as contact.creation, contact.propertyChange, contact.deletion, contact.merge, company.creation, deal.creation, deal.propertyChange and ticket.creation. Conversations add conversation.newMessage. Newer project-based apps use object.creation style names alongside these.

HubSpot batches. A request carries an array of JSON objects, always under 100, and a bulk import produces batches rather than one request per record. Each object has fields such as objectId, eventId, subscriptionId, portalId, appId, occurredAt and attemptNumber. Property change events add propertyName and propertyValue. Creation events carry the object ID but not the new record's properties.

Why send it to Sazabi

The array shape matches how Sazabi's Webhook Events source works. It turns a JSON array into one record per element, so a batch of 80 contact changes becomes 80 searchable records, with the payload under webhook.* attributes.

That gives you a log of what changed and when, next to your application logs. If an enrichment job or a sync to a billing tool misbehaves, you can look at the CRM events from the same minutes. Add a path suffix such as /hubspot to the intake URL and Sazabi stores it as webhook.path.

HubSpot payloads carry IDs and property values, not whole records. Plan to look up the full record in HubSpot when you need it.

Set it up in HubSpot

  1. In HubSpot, go to Development, then Legacy apps, and open your app. Select Webhooks.
  2. In Target URL, enter your Sazabi intake URL with the /hubspot suffix. HubSpot requires HTTPS. Select Save.
  3. Select Create subscription. Pick the object types and the event types. For property changes, pick the properties.
  4. Select Subscribe, then activate the subscription. New subscriptions are created paused, and nothing is sent until you activate them.

If your app is a project-based app on the current developer platform, set targetUrl and the subscriptions in the webhooks configuration file of the project instead. For a private app, open its Webhooks tab under Settings, Integrations, Private apps.

To test, open a subscription's details and use Test this subscription. Confirm the Test URL, then select Test. CRM payloads can contain personal data, so decide which subscriptions you want stored before you activate them.

Example payload

An abbreviated request using the field names in the HubSpot docs: one property change and one creation. It is an example, not a captured delivery.

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

The docs example names the type field eventType, while the field table calls it subscriptionType. Check a real delivery before you build a query on it.

What to watch for

  • Retries visible in the data. attemptNumber starts at 0. Search for records where it is above 0 to see how much HubSpot is re-sending.
  • Slow responses. HubSpot treats a response slower than five seconds to a batch as a failure.
  • Ordering and duplicates. HubSpot doesn't guarantee order or a single notification per event, and eventId isn't guaranteed unique. Use occurredAt to order events.
  • Paused subscriptions. A quiet stream right after setup usually means the subscription is still paused.
  • Privacy deletions. Privacy deletions also trigger the deletion event, so you can receive two notifications for one action.

The Intake page in the Sazabi dashboard shows ingestion volume per source. A sudden drop with CRM activity still going points to the subscription or the endpoint.

Retries

HubSpot re-sends failed notifications up to 10 times, spread over the next 24 hours with varying delays and some randomization. It retries when the connection fails, when your service takes more than five seconds, and on any 4xx or 5xx response. Webhook requests don't count against your app's API rate limits, and one app can hold 1000 subscriptions.

HubSpot signs requests with an X-HubSpot-Signature header, a SHA-256 hash of the app secret and the body. That isn't an HMAC. For ticket and billing activity next to your CRM, see Chargebee and Jira.

HubSpot webhook facts

Signatures: Sazabi doesn’t verify HubSpot requests and doesn’t reject unsigned ones. HubSpot’s X-HubSpot-Signature header is a SHA-256 hash of the app secret and the body, not an HMAC, so none of Sazabi’s signature options fits it. The Webhook Events source accepts any JSON POST to your intake URL, so the intake URL is the only credential. It’s hard to guess, so keep it private, and rotate the project’s public key if it leaks.

  • Events: Subscription types cover CRM objects, for example contact.creation, contact.propertyChange, contact.deletion, company.creation, deal.propertyChange and ticket.creation. (HubSpot docs, accessed Nov 8, 2026)
  • Payload: HubSpot sends an array of JSON objects in a single request, with batch sizes under 100 notifications, and does not guarantee order or a single notification per event. (HubSpot docs, accessed Nov 8, 2026)
  • Signing: HubSpot populates an X-HubSpot-Signature header with a SHA-256 hash of the app secret concatenated with the request body. (HubSpot docs, accessed Nov 8, 2026)
  • Retries: HubSpot re-sends failed notifications up to 10 times, spread over the next 24 hours, after a failed connection, a timeout over five seconds or any 4xx or 5xx response. (HubSpot docs, accessed Nov 8, 2026)

Frequently Asked Questions

Do HubSpot webhooks send JSON?

Yes. HubSpot posts an array of JSON objects, batching under 100 notifications per request. Sazabi stores each element of the array as its own record.

Why did my HubSpot webhook stop sending?

New subscriptions are created paused and must be activated. After that, repeated failures are retried up to 10 times over 24 hours, so check the subscription state and your endpoint response codes.

How do I spot retried HubSpot notifications?

Each notification carries an attemptNumber field that starts at 0. A value above 0 means HubSpot is re-sending after a failure.

Does Sazabi verify HubSpot signatures?

No. HubSpot’s X-HubSpot-Signature header is a SHA-256 hash of the app secret and the body, not an HMAC, so none of Sazabi’s signature options fits it. Sazabi doesn’t reject unsigned requests, so keep the intake URL private: it’s the only credential.

Sources

  1. Subscription types, batched JSON payload fields and example, target URL setting, creating and activating subscriptions, testing, signature header and retry rules (accessed Nov 8, 2026)
  2. Defining a webhook target URL and subscriptions in a project-based app, including object.creation style subscription types (accessed Nov 8, 2026)
  3. Request signature headers HubSpot sends, including X-HubSpot-Signature-v3 and X-HubSpot-Request-Timestamp (accessed Nov 8, 2026)
  4. Webhook Events source: a JSON array becomes one record per element, payload under webhook.* attributes, path suffix stored as webhook.path; signature verification with the Standard Webhooks and Custom HMAC options, and rejected deliveries (accessed Nov 8, 2026)