Skip to content
n8n + HubSpot

n8n and HubSpot: webhooks that arrive twice, handled once

How to run HubSpot automations on n8n: the three ways to trigger a workflow, why events arrive twice and out of order, how to stay inside HubSpot's limits, and what a self-hosted instance has to get right.

Connecting n8n to HubSpot is easy to start and easy to get subtly wrong. The nodes are there, the first test works, and the trouble arrives in production: events delivered twice, in a different order, in batches, to a URL that was only the test URL. The work is mostly in handling delivery properly, not in the API calls.

The case for the pair is straightforward. HubSpot's workflow engine is the right tool inside the CRM and weaker across systems, and n8n gives you item-level control, a Code node for the awkward cases, and, on a self-hosted Community Edition instance within n8n's licence terms, execution that is not metered (n8n counts a whole workflow run as one execution, not each step). The price is that you now operate the thing receiving HubSpot's webhooks, and that is a service with an address and an uptime.

Choosing the trigger

Three ways to start an n8n workflow from HubSpot

Each has a different failure profile, and the choice is mostly about which failures you can tolerate.

The HubSpot Trigger node

n8n's trigger node subscribes to object and property events through a HubSpot developer app, so it needs developer-app credentials and not just a private-app token. Events arrive from HubSpot in batches. HubSpot configures webhooks per app, with a single target URL, which means anything that re-registers it, including testing the trigger, is a way to point production events at a test URL, and a second workflow using the same app can fail to register. Check the registered target after every test.

Choose it whenYou want event-level granularity, such as a specific property change, and can manage a developer app.

A HubSpot workflow sending a webhook

A HubSpot workflow, with its enrolment rules, posts the properties you choose to an n8n Webhook node. The business rule stays in HubSpot where the team can read it, there is no developer app, and each workflow has its own URL. The webhook action sits on the higher workflow tiers, and the payload carries only what you selected.

Choose it whenThe trigger is a condition someone in sales or marketing owns, and the payload is small and known.

Scheduled polling with a search

A Schedule trigger asks the search API for records modified since the last run, storing the cursor in the workflow's static data. It needs no webhook and no public URL. It is also limited by the search endpoint, which has tighter rate limits than the rest of the API, caps the total results it will return for one query, and lags behind writes by a short interval. Check the current figures in HubSpot's search documentation.

Choose it whenMinutes of latency are acceptable, or n8n cannot be reached from the internet.

Handling an event

From a HubSpot event to a safe write, in order

  1. 01

    Respond immediately

    Set the Webhook node to acknowledge on receipt, not when the workflow finishes. HubSpot waits only a few seconds for a response to a batch (check the webhooks guide for the current figure) and retries on a timeout or an error, over a period of hours. A workflow that does slow work before answering invites a retry, which starts a second run of the same event.

  2. 02

    Verify the signature

    HubSpot signs webhook subscription requests and sends a request timestamp. Check the signature against your app's client secret in a short Code node before anything else runs, and reject requests older than the window HubSpot documents. For a workflow webhook action, check what authentication it offers and add a shared secret in a header where it does not sign. A public webhook URL that acts on any POST is an open door into your CRM.

  3. 03

    Split the batch into items

    A single delivery can hold many events. Split them so each one is an item, which also gives you per-event executions to read when something goes wrong.

  4. 04

    Drop what you have already handled

    Events carry an event ID, but HubSpot documents that it is not guaranteed to be unique, and that the same notification can occasionally arrive more than once. Build a key from the event ID, the object ID, the subscription type, the property name and the occurred-at time, and remove duplicates on that, using the node that remembers items across executions or a small store of your own. HubSpot retrying a delivery is correct behaviour on its side and a second action on yours.

  5. 05

    Fetch the record as it is now

    The event names the property that changed. By the time the workflow runs, the value may have changed again, and delivery order is not guaranteed. Read the current record, and compare the event timestamp before overwriting anything newer.

  6. 06

    Write with an idempotent call, in batches

    Use an update or an upsert against a unique property, not a plain create, and batch the calls within HubSpot's limits.

Node or HTTP request

When to use the HubSpot node and when the HTTP Request node

The node is fine for common operations. The HTTP Request node, using HubSpot credentials already stored in n8n, covers the rest.

You needUseWhy
Create or update one contact, company or dealHubSpot nodeThe node does it with credentials already configured, and the workflow stays readable.
Create or update many records in one callHTTP Request to a batch endpointThe batch endpoints take many records per call, which is the difference between inside and outside the burst limit.
Upsert on a unique property, such as an external IDHTTP RequestKeying on a stable external ID is what makes a write safe to repeat, and not every operation exposes it.
Associations with labels, custom objects, pipelinesHTTP RequestCheck the node's current operations first; the API surface is wider than the node's.
Find a record by email, to avoid creating a duplicateHTTP Request, read by email as an IDA direct read does not depend on the search index, which lags writes. Search-then-create races itself.
Page through thousands of recordsHTTP Request with paginationGives control over page size and pacing; Return All in a node fetches every page in one execution.
Worked example

A new contact is enriched once, however many times HubSpot tells us

The set-up

Illustrative, not a client result. Form submissions create contacts. A third-party company-data API, charged per lookup, supplies industry and headcount from the email domain, which are then written to the company.

What it comes to

On a self-hosted Community Edition instance the n8n side is not metered by execution, so the cost that matters is the per-lookup charge from the enrichment API. The dedupe and the filter are cost controls as much as correctness ones: without them the same domain is paid for every time it recurs.

  1. 01

    Webhook acknowledges and verifies

    The creation event arrives, the signature is checked, the response goes back immediately.

  2. 02

    Remove duplicates on the dedupe key

    A redelivered creation event stops here, before it can spend a lookup.

  3. 03

    Skip free-mail domains and known companies

    A filter drops personal email domains and companies that already hold the enrichment properties, which is where most of the lookups would otherwise go.

  4. 04

    Look up, then write in a batch

    One lookup per new domain. The properties are written to the company by update, not create, and batched with the other items from the same delivery.

Failure modes

What goes wrong with n8n + HubSpot

The patterns that turn up on this pair specifically, and what we do about each one.

  • 01

    Test URL in production, or no URL at all

    n8n gives every Webhook node a test URL and a production URL, and the test one only works while the editor is listening. A subscription pointed at the test URL works in the demo and fails silently afterwards. The production URL only receives events once the workflow is active. Behind a reverse proxy, the instance's public webhook address has to be configured, or n8n advertises an internal one HubSpot cannot reach.

  • 02

    Deliveries that repeat and arrive out of order

    HubSpot retries when a delivery fails or times out, and does not promise ordering between events. Without a dedupe key you act twice; without a timestamp check, an older event can overwrite a newer value. Both are cheap to prevent and expensive to find afterwards.

  • 03

    The workflow triggering itself

    n8n updates a property that the subscription watches, HubSpot emits an event, n8n runs again. Event payloads carry a change source and a source ID, which for an integration is the app's ID, so the cheapest loop guard is to ignore changes that came from your own app; confirm the exact fields in the current webhook documentation. Also write only when the value differs.

  • 04

    Rate limits and the retry that duplicates

    HubSpot limits requests in a short burst window and per day, with figures that vary by tier, so check them for yours. The HTTP Request node can batch items and wait between batches, and has a Retry on Fail setting. Use retries only on calls that are safe to repeat, such as reads, updates and upserts. A retried plain create is how a rate-limit blip turns into duplicate contacts.

  • 05

    Search-then-create racing the index

    HubSpot's search index trails writes by a short interval, so a contact created a moment ago may not appear in a search. A workflow that searches by email and creates on no result will create a second copy when two events for the same person arrive close together. Read by email directly, or upsert on a unique property, and do not make a search the guard for a create.

  • 06

    Customer data left in the execution log

    Every HubSpot payload contains personal data, and saved executions store it in the n8n database. Left on defaults, the instance quietly accumulates a copy of your contacts that nobody planned to secure, back up or delete. Save only failed executions, prune on a schedule the business has agreed to, and keep production and sandbox credentials separate.

  • 07

    A single execution trying to hold a whole portal

    Fetching tens of thousands of records into one execution can exhaust memory and affect everything else on the instance. Page in modest chunks, hand each chunk to a sub-workflow, and do bulk backfills with HubSpot's import or a script, not a workflow processing item by item.

The honest limit

When n8n should not be what talks to HubSpot

Use HubSpot's own workflows when the whole job is inside HubSpot. Setting properties, rotating owners, sending internal notifications and enrolling into sequences need no extra host, no credentials and no second place to look. Add n8n for the parts that cross a system boundary.

Do not self-host if nobody can own the server. You become the party receiving the CRM's webhooks, and an outage means events retried and then lost. If the appeal is the cost model, n8n Cloud or Make may be the better fit; the n8n platform page and the self-hosting article set out the trade.

Do not use per-item workflows for bulk work. A historical backfill, a mass reassignment or a one-off clean-up belongs in HubSpot's import tools or a script with batching, where it is quicker, cheaper and does not occupy the same instance that handles live events. And where event order matters absolutely, such as anything resembling a ledger, put a queue between HubSpot and the workflow.

Rate limits, plan tiers and which modules exist change over time. Where this page gives a figure it shows how it was derived; for everything else, confirm against the vendors’ current documentation before sizing a build. Skofi holds no partnership, certification or reseller arrangement with any vendor named here.

Questions

n8n + HubSpot, specifically

Yes: a HubSpot node for common operations on contacts, companies, deals and more, and a HubSpot Trigger node for events. The trigger works through a HubSpot developer app, which needs its own credentials separate from a private-app token. We are not affiliated with either vendor. For anything the node does not expose, the HTTP Request node reaches the rest of the API with the same stored credentials.

Sources

Statements about what a platform, regulator or provider says come from their own pages. Rules and limits change, so check the current page before you rely on one.

Page copy drafted with AI assistance. Skofi is accountable for it. Editorial policy

Start here

Tell us about the process that keeps costing you.

A 15-minute call is usually enough to say whether this is an automation, an integration, or something that should be built, and whether we are the right people for it.

Book a 15-minute callsaveez@skofi.tech

What happens on the call

  • 15 minutes, no deck
  • We map the process on the call
  • A written scope, or an honest no
Book a call