Automate Typeform to HubSpot with dedupe, enrichment, and Slack alerts in Make.com. Get step-by-step logic, field mappings, and error handling.
Introduction
If you run lead capture on Typeform, the painful part usually starts after the submit button. Someone copies answers into HubSpot, you get duplicates when the same lead submits twice, and nobody can tell you what changed, when it changed, or why a Slack alert fired.
In this guide, you will implement a robust Typeform to HubSpot enrichment workflow, with Slack alerts and audit logging, using Cross-Platform Automation (XPA) in Make.com. You will end up with a deterministic pipeline: every form submission becomes a single HubSpot contact update, with the right Slack message and a traceable record of what happened.
By the end, you will have a production-grade build you can safely run at volume.
What You'll Need
- Make.com (paid plan recommended for reliability, retries, and larger operation counts)
- Typeform form with fields that include at least one of: email, phone, or a stable identifier
- HubSpot account with API access, and custom properties created for any Typeform fields you want to store
- Slack workspace, plus a channel where you post lead alerts
- Google Sheets (or equivalent) for audit logging, idempotency keys, and troubleshooting
Important prereqs:
- You must have a reliable dedupe strategy, typically email-based.
- You need to know which HubSpot properties are strings vs numbers to avoid schema errors.
How It Works (The Logic)
The logic of this XPA is simple to describe, but careful to implement.
- Trigger: A new Typeform response arrives in Make.com.
- Normalize: You clean and standardize values, especially email (trim, lowercase).
- Idempotency check: You check your log for a submission key so retries do not create duplicate updates.
- HubSpot dedupe: You search HubSpot contacts by email. If found, you update. If not found, you create.
- Enrichment layer (optional): You add extra HubSpot fields (for example job title, company details, lifecycle source mappings) based on form answers, and optionally additional enrichment steps.
- Slack routing: You notify Slack on creation and also on “meaningful update” events, with a link to the HubSpot contact.
- Audit log: You write one row to Google Sheets with the submission ID, action taken (create/update), HubSpot VID (when available), and Slack status.
- Error route: Any failure routes into an error handler that logs details and alerts ops in Slack.
Step-by-Step Setup
1) Set up your Typeform payload to support dedupe
In Typeform, ensure you capture:
- Email (preferred, required for best dedupe)
- First name, Last name
- Company
- Phone (optional but useful fallback)
- Lead source fields like UTM source and UTM medium if you use them
Also ensure you can access a stable Typeform submission identifier (Typeform response ID). You will use that as an idempotency key.
2) Create custom properties in HubSpot
In HubSpot, create properties for your Typeform fields you want stored. At minimum:
- firstname (standard)
- lastname (standard)
- company (standard)
- phone (standard)
- jobtitle (standard or custom)
- utm_source and utm_medium (custom properties if you want to store them)
- Any lead categorization field you collect in Typeform (for example lead_source, lead_stage)
Gotcha: if you map a date field as a string in HubSpot, later automation and reporting gets messy. Match property types to how you will write values.
3) Build the Make.com scenario skeleton
Create a new Make.com scenario, then add these modules in order:
-
Typeform: Watch responses (trigger)
- Output what you need: response ID, email, name, company, job title, phone, UTM fields.
-
Tools: Set variables / data mapping
- Create normalized variables:
- normalized_email = lowercase(trim(email))
- submission_key = response_id (or concatenate with form ID)
- Create normalized variables:
-
Google Sheets: Search rows (idempotency)
- Spreadsheet: Lead_Ingestion_Log
- Search column: submission_key
- If found, route to a Stop branch.
-
HubSpot: Search contacts (dedupe by email)
- Search by normalized_email.
-
Router
- Condition A: contact exists → update branch
- Condition B: contact not found → create branch
4) Implement the HubSpot create vs update payload
In both branches, map Typeform fields to HubSpot properties.
Update branch (contact exists):
- Use the found contact identifier (often a VID returned by the HubSpot module).
- Set properties you want to overwrite.
Create branch (contact not found):
- Create a new contact with:
- firstname / lastname
- company
- jobtitle
- phone
- lifecycle or lead source properties
Gotcha you want to avoid: sending empty strings can overwrite real values you already have in HubSpot. In Make.com, handle this with conditional mapping, for example “only set jobtitle if not empty”.
5) Optional enrichment, done safely
If your enrichment is derived from Typeform answers (for example mapping a self-selected form option to lead_source or industry), keep it deterministic.
If you call third-party enrichment (like company enrichment based on domain or LinkedIn), put it behind a condition:
- Only enrich when the HubSpot contact is new, or when key fields are missing.
Do not enrich on every resubmission. That creates cost and rate-limit pressure.
6) Slack notifications that do not spam your team
Add these Slack behaviors:
- On create: post a “New lead created” message.
- On meaningful update: post a message only when at least one tracked field changes (for example job title, company, lead source).
Slack message contents (keep it scannable):
- Lead name and email
- Company and job title
- Source (UTM or your lead_source)
- Link to the HubSpot contact
Security tip: do not paste unnecessary personal data into Slack. The HubSpot link is where your team should inspect full details.
7) Write an audit log row in Google Sheets
After HubSpot create/update succeeds, write one row to Lead_Ingestion_Log with:
- submission_key
- typeform_response_id
- action (create or update)
- hubspot_contact_id or vid
- slack_status (sent or skipped)
- timestamp
This row becomes your debugging tool when something feels off.
8) Add the error handler route
In Make.com, add an error handler route that:
- Writes the error message into Google Sheets (columns like error_message and error_step)
- Posts to Slack in an ops channel
- Includes submission_key and email so your team can reconcile quickly
Gotcha: make sure the error handler does not attempt to create the contact again automatically. If the failure happened after create but before logging, your dedupe logic should prevent duplicates on retry, but only if your idempotency check is correct.
9) Test the failure modes you will actually see
Run tests for:
- New submission with a new email (create path)
- Submission with an existing email (update path)
- Same submission retried (idempotency path, should stop)
- Missing email (decide your policy, either reject or route to manual review)
- Slack failure (HubSpot should still update, Slack should log failure)
Real-World Business Scenario
A B2B agency routed inbound campaign leads through Typeform, but their CRM data quality broke after a week. Leads were duplicated when people submitted twice on poor mobile connections, and sales spent time figuring out which submissions were “real”.
After implementing this Typeform to HubSpot enrichment workflow in Make.com with dedupe-by-email, idempotency using the Typeform response ID, and Slack notifications with HubSpot links, they got:
- Fewer duplicates because retries updated the same HubSpot contact
- Faster handoff because Slack messages included the fields sales cares about
- Traceability because every submission key had a row in Google Sheets
That is the point of Cross-Platform Automation (XPA), you connect multiple systems, but you preserve one consistent operational truth across them.
If you want a broader view of how we structure these Cross-Platform Automation (XPA) projects, start with Cross-Platform Automation (XPA).
Common Variations
- Filter Slack notifications by lead score or form answers
- Only notify Slack for leads above a certain company size, or only for specific campaign types.
- Route to manual review when email is missing or malformed
- Add a validation step before HubSpot calls. If email is invalid, write to Google Sheets and alert ops.
- Add HubSpot property change detection
- Before writing, compare existing properties vs incoming values and only notify Slack when something meaningful changed.
What You Built
You built an advanced Typeform to HubSpot enrichment automation in Make.com that:
- Normalizes Typeform submissions
- Prevents duplicate processing with idempotency
- Uses HubSpot for dedupe by email
- Creates or updates contacts reliably
- Sends Slack alerts on create and meaningful updates
- Logs every run to Google Sheets
- Routes errors into an ops-visible Slack channel
This is the kind of workflow Olmec Dynamics builds for teams that need CRM hygiene, fast lead handoff, and production-grade reliability. If you want help wiring the exact modules and mappings for your stack, see what we do at Olmec Dynamics and we will help you get to a stable XPA setup quickly.