Automate Typeform to HubSpot contact creation with Make.com webhooks, idempotent upserts, field mapping and error handling. Step-by-step for ops teams.
Introduction
You run a high-volume lead capture form in Typeform. Right now a team member manually exports submissions, cleans data, and imports into HubSpot, or you rely on the native Typeform integration and see duplicates, missing fields, or wrong owners. This adds hours of daily manual work and creates bad data in your CRM.
By the end of this guide you will have a production-ready design and a detailed Make.com build that receives Typeform webhooks, normalises fields, checks HubSpot for an existing contact by email, then updates or creates the contact with robust error handling and logging.
What You'll Need
- Typeform account with the form you want to receive submissions from (Pro or paid plan if you need webhooks / advanced features).
- HubSpot account with API access (Private app or OAuth token with CRM objects write and read scopes). Paid tiers are not strictly required, but API rate limits and limits on custom properties vary by plan.
- Make.com account with HTTP/Webhook, JSON, and HubSpot modules (paid Make.com plan recommended for higher execution quotas).
- A stable mapping document: Typeform question IDs to HubSpot property names.
How It Works (The Logic)
When Typeform receives a submission it calls a webhook URL hosted by Make.com. Make.com parses the JSON payload, extracts key fields (email, firstname, lastname, phone, company, custom fields), normalises values, then queries HubSpot by email. If HubSpot returns a contact, Make.com updates that contact with merged properties. If no contact exists, Make.com creates a new contact. Every success or failure is logged to a Google Sheet or a Make.com Data Store for later inspection.
Step-by-Step Setup
-
Prepare Typeform
- In Typeform settings enable Webhooks and add a new webhook pointing to the Make.com custom webhook URL (you will create this URL in step 2).
- Ensure your form has a required email field. Record the Typeform question reference IDs (use the question "ref" or "id" rather than visible label).
-
Create the Make.com Scenario and Webhook
- Module 1: Webhooks > Custom Webhook (Watch for incoming requests). Create a new webhook and copy the generated URL.
- In Typeform paste that URL into the webhook you added in step 1 and enable it. Submit test responses to confirm Make.com receives the payload.
- Gotcha: Typeform payload nests answers in an answers array. Use a JSON transformer to map question IDs to friendly keys.
-
Extract and Normalise Fields
- Module 2: Tools > JSON > Parse JSON (or use a Set variable module) to flatten the payload. Map Typeform answer items by their field id or reference.
- Normalize rules to implement here:
- Trim whitespace for strings.
- Lowercase emails.
- Convert phone numbers to E.164 using a small JS transformer or a ready library if you host externally.
- Map to hubspot_property keys, for example:
- email -> email
- first_name -> firstname
- last_name -> lastname
- phone -> phone
- company -> company
- job_title -> jobtitle (or your custom property key)
-
Idempotency and Submission Tracking
- Module 3: Data Store > Get Item (Make.com Data Store) keyed by Typeform response_id. If entry exists, stop processing to prevent double writes when Typeform retries.
- If not present, create a Data Store entry with the submission_id and a timestamp, then continue.
- Gotcha: Use this early in the flow so retries do not create duplicate HubSpot actions.
-
Search HubSpot for Existing Contact
- Module 4: HubSpot > Search Contacts (or HTTP module to call HubSpot CRM v3 Search endpoint).
- Search by email property. If HubSpot returns a match, capture the contactId and existing properties.
- Mapping note: HubSpot deduplicates by email in many flows but you should not rely on automatic dedupe. Always check search results.
-
Upsert Logic
- Conditional Router: If search returned contactId then route to Update path, else route to Create path.
- Update path: HubSpot > Update Contact (pass contactId). Map only non-empty fields from the Typeform payload to avoid blanking existing values. Optionally merge owner or lifecycle stage only when present.
- Create path: HubSpot > Create Contact. Pass the full properties object, ensure email present.
- Gotcha: Use the HubSpot module that supports OAuth tokens or private app tokens. If you use HTTP calls, set Accept and Content-Type to application/json and include your Authorization: Bearer TOKEN header.
-
Error Handling and Retries
- Add an Error Handler sub-scenario in Make.com for transient HTTP errors (429, 5xx). Implement exponential backoff and up to 3 retries.
- For 4xx client errors, log the payload and the error response in your Google Sheet and mark the Data Store entry as failed with the error message.
- Always capture HubSpot response bodies and request payloads to logs, redacting PII when appropriate.
-
Observability and Post-action Logging
- Module final: Google Sheets > Append Row (or Data Store) containing: submission_id, email, contactId, action (created/updated), hubspot_response_id, timestamp, status.
- Optionally send a Slack message for failures above a threshold using Slack > Send Message.
-
Production Checklist
- Run a full end-to-end test using a staging Typeform and a non-production HubSpot account or a test property namespace.
- Validate idempotency by replaying the same webhook twice.
- Monitor API rate limits in HubSpot and throttle if you expect bursts.
Real-World Business Scenario
A B2B events agency captures webinar signups with Typeform and needs to push those leads into HubSpot with the correct owner and lifecycle stage. Before automating they had duplicated contacts and missed assignment rules. Using this Make.com scenario they implemented email-first deduplication, enrichment of company name from the form, and automatic owner assignment when the form included an account manager selection. The result was accurate lead routing and 90% fewer duplicates in HubSpot within two weeks.
Common Variations
- Replace Make.com with a serverless webhook consumer (Node.js on AWS Lambda) if you need complex enrichment (company lookups, IP-to-country, reverse-prospecting) before writing to HubSpot.
- Enrich leads with external APIs (Clearbit, Pipl) in a middle step and add those properties to HubSpot during upsert.
- Add a conditional step to only create HubSpot deals for submissions that include a budget field above a threshold.
What This Delivers
You now have a clear, advanced pattern for moving Typeform data into HubSpot using Make.com, with idempotent processing, explicit field mapping, upsert logic, and production-ready error handling. If you want help building or maintaining this exact flow for your business, see our implementation services at Olmec Dynamics in the services section of our site using the descriptive link to Olmec Dynamics services. We build and maintain integrations like this for companies that need reliable, auditable CRM pipelines.