HubSpot Trigger
Triggers a workflow when your HubSpot app receives webhook deliveries (contact / deal / company / property changes).
HubSpot webhook target URLs and event subscriptions are configured at the App level in the HubSpot Developer Portal, not via API. HubSpot publishes a single target URL per app and fans events across all portals (HubSpot accounts) that installed the app. Workflow-automation acts as one such target.
Requires a HubSpot connection configured with the Private App Access Token (for outbound API calls) AND the Client Secret (for verifying inbound webhook signatures).
Auth model — important
HubSpot has two authentication models. They serve different purposes:
- Private app (access token): per-portal, used for outbound API calls from action nodes. Private apps don't expose webhook subscriptions.
- OAuth (public) app (client secret): webhooks live here. The webhook URL is configured app-level in the Developer Portal; events arrive tagged with the originating
portalId.
If your workflow only needs to call HubSpot, the access token is enough. To receive events via the HubSpot Trigger, you also need an OAuth app installed into your portal, and its Client Secret on the connection.
HubSpot is moving away from legacy public apps
In the HubSpot Developer UI these are now listed under "Legacy Apps" (German: Alte Apps) with a banner noting they won't receive future updates. HubSpot's stated long-term path is the newer Developer Projects framework. The webhook integration we describe here works fine against a legacy public app today; if HubSpot deprecates them in the future, the trigger will need to be re-implemented against Projects. We will track the migration when HubSpot announces a date.
Webhook URL is per-connection, not per-workflow
https://<your-deployment>/api/conn-webhook/<connection-webhook-token>Fetch it from the connection's webhook-info endpoint, or read it from the trigger node's banner in the workflow editor:
bash
curl -H "Authorization: Bearer $TOKEN" \
https://<your-deployment>/api/connections/<connection-id>/webhook-info \
| jq '.data.url'The same URL services every hubspot_trigger workflow built on this connection. The dispatcher fans deliveries to all matching workflows.
Setup — step by step in the HubSpot Developer Portal
The exact menu labels differ by language. The English / German pairs are noted below.
1. Create a Public (OAuth) Legacy App
- Open the HubSpot Developer Portal and sign in.
- Left sidebar → Legacy Apps (German: Alte Apps). The URL
/applicationsredirects here automatically. - Click Create Legacy App (Alte App erstellen).
- Choose Public (Öffentlich — "For many accounts"). Not Private; private apps don't support webhooks.
- Set a meaningful app name (e.g.
workflow-automation-trigger).
2. Configure Authentication
- Switch to the Authentication tab (Authentifizierung).
- Under Redirect URLs (Weiterleitungs-URLs), add a URL.
localhostis acceptable for dev — HubSpot's UI accepts it without thehttp://prefix; the dropdown defaults tohttp://. A redirect URL is required even if you never run the OAuth flow. - Under Scopes (Bereiche) → + Add new scope (Neuen Bereich hinzufügen). Add at least one scope matching the events you want, e.g.
crm.objects.contacts.readfor contact events. The defaultoauthscope is added automatically and required. - Click Create app (App erstellen) at the bottom of the page. The app gets a numeric ID.
3. Copy the Client Secret
Still on the Authentication tab, scroll to App Credentials (App-Anmeldeinformationen):
- App ID — numeric, used in OAuth install URLs.
- Client ID — UUID, used for OAuth flow.
- Client Secret (Client-Geheimnis) — click Show (Anzeigen) to reveal, then Copy (Kopieren). This is what goes into the workflow-automation connection.
4. Configure Webhooks
- Left sidebar inside the app → Webhooks.
- Under Target URL (Ziel-URL), paste the webhook URL from the connection. The URL field has an
https://prefix baked in — paste only the host + path (e.g.wf-dev.ruvix.io/api/conn-webhook/01KR…). - Click Save (Speichern) at the bottom of the page. You must save before creating subscriptions — HubSpot tooltips you if you try.
- Click Create subscription (Abonnement erstellen) — top right.
- Pick the Object type (Objekttyp) you want (Contact, Deal, Company, …). Each subscription is one object × one event type.
- Pick the Event type (Welche Events beobachten?) — typical choices: Created (Erstellt), Deleted (Gelöscht), Property changed (Eigenschaft geändert), Merged, Restored.
- Leave "Use extended object support" (Beta) off unless you specifically need it.
- Click Subscribe (Abonnieren). The subscription appears in the table.
- Activate the subscription — this is critical. New subscriptions are created in Pausiert (Paused) state by default and fire nothing. Click into the row, select the subscription's checkbox, then click ▶ Aktivieren (Activate) in the row of bulk actions that appears. The status dot should turn green and read Aktiv. Without this step the table shows
Gesamtanzahl: 0forever and HubSpot's Monitoring → Webhooks tab will also show zero deliveries.
5. Install the app in a portal
The OAuth app does nothing until at least one HubSpot portal installs it. Without an install there's no portal context for HubSpot to fan events from.
On the Authentication tab, copy the Sample Installation URL (OAuth) (Beispiel-Installations-URL) — looks like
https://app-eu1.hubspot.com/oauth/authorize?client_id=…&redirect_uri=…&scope=….Open that URL in a browser session logged into the HubSpot portal you want to test from (often the dev portal itself, which doubles as a CRM).
Pick the account → consent → if the app is unverified, type Ich akzeptiere das Risiko / I accept the risk in the confirmation box → Verknüpfen (Connect).
You must complete the OAuth token exchange to commit the install. HubSpot redirects to your configured
redirect_uriwith a one-time?code=…. If that redirect target doesn't run server-side code that POSTs the code to/oauth/v1/token, the install remains in a pending state and webhooks never fire — even though the consent screen makes it look done.For local dev where
redirect_uri=http://localhost(no server running), grab thecodefrom the failed browser address bar and exchange it manually:bashcurl -X POST https://api.hubapi.com/oauth/v1/token \ -d grant_type=authorization_code \ -d client_id=<CLIENT_ID> \ -d client_secret=<CLIENT_SECRET> \ -d redirect_uri=http://localhost \ -d code=<CODE_FROM_REDIRECT>A successful response includes
access_token,refresh_token,hub_id,scopes. That commits the install permanently.
6. Paste the Client Secret into the workflow-automation connection
- In the workflow-automation UI → Connections → open the HubSpot connection.
- Paste the Client Secret you copied in step 3 into the Client Secret field. Leave the Private App Access Token alone.
- Save. The connection's
webhook_statusflips fromerrortopending_manual_setup(no error, just the standard state for any manually-configured webhook).
7. Build a workflow
Trigger node = HubSpot Trigger, Connection set to the connection above, events filter set to the matching subscription type (e.g. contact.creation) or ["*"]. Publish.
Output
HubSpot delivers an array of events per POST (batched). The trigger output reflects that — your downstream nodes should iterate or filter.
| Field | Description |
|---|---|
body | Array of subscription events |
body[].subscriptionType | Event type (e.g., contact.creation, deal.propertyChange) |
body[].objectId | The HubSpot object's ID |
body[].portalId | Which HubSpot portal fired the event (relevant for multi-tenant apps) |
headers.X-HubSpot-Signature-v3 | Signature (already verified before the workflow runs) |
headers.X-HubSpot-Request-Timestamp | Used as part of the signature payload |
The trigger's dispatch-side events filter matches against the first event's subscriptionType — workable for batches that share a type. Use ["*"] if you want every batch regardless and filter downstream.
How it works
- Every POST is verified with HubSpot's v3 signature scheme:
signature = base64(HMAC-SHA256(client_secret, method + full_url + raw_body + timestamp))compared to theX-HubSpot-Signature-v3header. - Deliveries older than 5 minutes are rejected as replay attempts (timestamps are in milliseconds).
Client Secret required
The HubSpot Trigger refuses to publish if the connection is missing its Client Secret. Deliveries cannot be authenticated without it.
HubSpot doesn't expose a registration API
Target URLs and event subscriptions live in the OAuth app's configuration. HubSpot doesn't allow programmatic mutation of app settings — the Developer Portal is the only path.