Lead Generation · n8n

Auto-Enrich New Leads in HubSpot the Moment They Submit a Form

Captures new leads via a webhook and automatically creates or updates enriched contact records in HubSpot with structured data. B2B sales teams save hours of manual data entry and respond to hot leads faster.

difficulty Beginnersetup 30 minresult Every new lead submission is instantly turned into a fully populated HubSpot contact with company, email, and name fields filled in — ready for your sales team to act on.
  1. 1

    Step 1 — Create a Webhook trigger to receive leads

    Add a Webhook node as the first node. Set HTTP Method to POST and copy the generated webhook URL. Paste this URL into your lead capture form (e.g. Typeform, Webflow, or a custom form) as the form submission endpoint. This node will receive the raw lead data every time someone submits the form.

  2. 2

    Step 2 — Map and clean the incoming lead fields

    Add a Set node after the Webhook. Create fields named email, firstname, lastname, and company. Map each one to the corresponding value from the webhook body using expressions like {{ $json.body.email }}, {{ $json.body.first_name }}, {{ $json.body.last_name }}, and {{ $json.body.company }}. This standardises the data regardless of which form tool sent it.

  3. 3

    Step 3 — Check whether the lead email is valid before proceeding

    Add an If node to guard against empty or malformed emails. Set the condition to: {{ $json.email }} is not empty. Connect the true branch to the next step. The false branch can be left unconnected or connected to a Slack or email alert node to flag bad submissions.

  4. 4

    Step 4 — Create or update the contact in HubSpot

    Add a HubSpot node on the true branch of the If node. Set Resource to Contact and Operation to Upsert (create or update). In the Email field enter {{ $json.email }}. Add additional fields for First Name mapped to {{ $json.firstname }}, Last Name mapped to {{ $json.lastname }}, and Company Name mapped to {{ $json.company }}. In the node credentials, connect your HubSpot Private App token. The upsert operation ensures no duplicate contacts are created.

  5. 5

    Step 5 — Confirm success with a response

    Add a Respond to Webhook node at the end of the flow. Set Respond With to Text and enter a message like Lead received and saved to CRM. This sends an HTTP 200 response back to the form tool confirming the webhook was processed, which prevents retry loops in tools like Typeform or Webflow.

Frequently asked questions

What if my form sends field names differently from email, first_name, or company?

Simply update the expressions in the `Set` node (Step 2) to match your form's exact field names. For example if your form sends `email_address` instead of `email`, change the expression to `{{ $json.body.email_address }}`. No other steps need to change.

Will this create duplicate contacts in HubSpot?

No. The HubSpot node uses the Upsert operation, which checks for an existing contact by email address. If a contact already exists it updates their record; if not it creates a new one. This keeps your CRM clean automatically.

Can I enrich the lead with company data from a third-party tool like Clearbit before saving to HubSpot?

Yes. Insert an `HTTP Request` node between the `If` node and the `HubSpot` node. Call the Clearbit Enrichment API using the lead's email, then merge the returned company size, industry, or LinkedIn data into the Set node fields before the HubSpot upsert runs. This keeps the workflow under 5 nodes if you replace the Respond to Webhook node, or you can extend to 6 nodes for a more complete flow.

About this recipe. Recipes on FlowRecipesHub are written for business owners, not developers, and are tested before publishing — how recipes get made. Some ingredient links are affiliate links that cost you nothing — full disclosure.