The HubSpot webhook API delivers at least once and in no fixed order. One request carries a batch of events, the same event can arrive twice, retries arrive mixed in with new events, and any error status, a client error included, gets the whole batch sent again. Treat each event as a hint that something changed, and build the handler for that.
Each note above says what HubSpot does and what to plan for, citing HubSpot's Webhooks API guide and its request validation pages, with the day we last checked it.
Build the handler in this order
Answer, then work. Store the batch, answer with success at once, and process the events in the background. Answer with success to a batch you chose to ignore, too.
Verify the signature on the raw bytes, before you parse the JSON. The v3 signature covers the method, the URI and a timestamp; v1 covers no time, so bound replays yourself. The webhook signature checker shows where a mismatch comes from.
Deduplicate on several fields. The eventId is not unique, so combine portalId, subscriptionId, eventId, objectId and occurredAt.
Order by occurredAt, and drop an event older than the state you already hold.
Subscriptions belong to the app
A subscription applies to every account that installs the app, and each event names its account in portalId. A property change subscription watches one property and stays silent in an account that lacks it. The last modified date cannot be watched, so you cannot use it to hear about every change.
Some single changes fire two events. An association change fires one for each side, and a privacy deletion also sends a plain deletion for the same contact.
What to do next
The webhooks journal keeps only a short history, so an outage longer than that loses events for good. A scheduled read of recently modified records catches what a webhook never delivered, and those reads count against HubSpot API limits.
For HubSpot's changes in Oneprofile, there is no handler to write: connect HubSpot through Oneprofile's app and turn on live changes for a table imported from it.
