Skip to main content

Growth – Every lead lands in your CRM instantly: send Survio demo requests to a sheet or HubSpot

Turn a Survio form into a lead pipeline: every demo request becomes a row in a Google Sheet with an e-mail to you, or a new contact in HubSpot. Guide with n8n and ready-made workflows.

Written by Success Team Survio

Which case is for you?

Case A – simple, for everyone: every demo request lands in a Google Sheet you use as a CRM, and you get an e-mail.

Case B – for teams using a CRM: every demo request becomes a lead in HubSpot, ready for your sales team.

A visitor fills in your demo request form, and seconds later the lead is in your CRM. A small business gets a new row in its leads sheet and an e-mail it can reply to; a sales team gets a new contact in HubSpot. Either way, you're talking to the lead while they're still on your website.
​

This is the e-mail you get for every new demo request in Case A:
​

New demo request e-mail in Gmail


​

And this is the new contact in HubSpot in Case B:
​

HubSpot contact created from a demo request: lifecycle stage Lead and the request in Message

How this works. Survio sends each completed response to a webhook URL. An automation tool (we use n8n in this guide) receives it and writes the lead where you work. Survio does the sending, n8n does the rest.

New to webhooks in Survio? Start with Webhooks: send responses to your other tools in real time, then come back here.
​

What you'll build

Both cases start the same way: a short demo request form on your website, sent to n8n by a webhook.

At a glance

Case A: a sheet as your CRM

Case B: HubSpot

Result

Each request is a row in Google Sheets with a Status column, and you get an e-mail

Each request is a new contact in HubSpot CRM, ready for your sales team

Tools

Survio, n8n, Google Sheets, Gmail

Survio, n8n, HubSpot

Best for

A small business that follows up on leads by itself

A sales team that already works in HubSpot

Before you start

  • A Survio survey on a paid plan. Webhooks aren't available on the Free plan, and each plan allows a set number of webhooks per survey (see the webhooks article).

  • An n8n account, n8n Cloud or self-hosted.

  • Case A: a Google account for Google Sheets and Gmail. Case B: a HubSpot account.

In this guide we use a short demo request form: name, work e-mail (an e-mail question), company, team size (a choice question) and an optional "What would you like to see in the demo?". Your form can look different; you map your own questions in Case A or Case B.
​

Step 1 — Put the form on your website

  1. Open your survey, go to Get responses and choose On the web.

  2. Pick Pop-up window and set when it appears. For a short form, switch on Hide the welcome page so visitors start with the first question.

  3. Click Embed on website and paste the code into your website.

Pop-up window settings for the survey in Survio
Embed code for the pop-up window

More options, such as a button or a side-bar widget, are in Embed a survey on your website.
​

Step 2 — Case A only: prepare the leads sheet

  1. Create a new Google Sheet and rename its first tab to leads.

  2. In row 1, type the column headers: Response ID, Received, Name, E-mail, Company, Team size, What they want to see, Status and Language.

  3. Select the cells of the Status column below the header, choose Insert → Dropdown, add the options New, Contacted and Done (use Add another item), and click Done.

Your sheet is now a simple CRM. New leads arrive as New. When you've called or written to someone, switch them to Contacted, and to Done when the deal is closed or lost. Filter the Status column to see who still needs an answer.

Step 3 — Create the webhook in n8n

  1. In n8n, create a new workflow and add a Webhook node as the trigger.

  2. Set HTTP Method to POST.

  3. Switch to the Production URL tab and copy the address.

  4. Click Publish. The production URL only accepts deliveries once the workflow is published.

n8n Webhook node with HTTP Method POST and the Production URL tab
Published button in the n8n editor

Use the Production URL, not the Test URL. The Test URL only listens while the editor is waiting for a test event, so Survio's deliveries fail as soon as you close it. Survio retries a failed delivery for about a day, and after 5 days of failures it switches the webhook off.

Step 4 — Connect the survey in Survio

  1. Open your survey and go to Get responses.

  2. In the left sidebar under Automations & Integrations, select Webhooks and click + Add a webhook.

  3. Paste the n8n Production URL into Webhook URL and click Save webhook. The webhook is switched on straight away.

Add a webhook dialog in Survio with the n8n Production URL filled in
Saved webhook in Survio, switched on


​

Step 5 — Send a test request and find your question ids

  1. Fill in your form through its normal link and submit it. Survio sends only completed responses, so click through to the end.

  2. In n8n, open the Executions tab. The delivery arrives within a few seconds.

  3. Open the execution and click the Webhook node. Expand body, then data, then answers. Each answer shows its question.id, the question label and the answer.

  4. Write down the id of each question. You can also click Pin to keep building against this response without submitting the form again.

Webhook node output in n8n with a demo request

Always pick answers by question id. Answers arrive as a list. If you later add a question to the form, positions in the list shift. Question ids never change.

The lead's e-mail is in the answers. Don't use data.email: it stays empty when the e-mail comes from an e-mail question. Read it from the answer to your e-mail question.

Case A — A sheet as your CRM, plus an e-mail

The workflow has three steps after the webhook: Prepare lead picks the answers out of the response, Save lead to sheet adds the row, and E-mail the new lead tells you about it.
​

Prepare lead

  1. Add an Edit Fields (Set) node after the Webhook node and rename it to Prepare lead.

  2. Under Fields to Set, add one field for each column of your sheet and keep its type String. The field name must match the column header exactly; the value is the expression below.

  3. Replace the question ids (90403243 and so on) with the ids you wrote down in Step 5, and Europe/Prague with your time zone.

Field name

Value

Response ID

{{ $json.body.data.responseId }}

Received

{{ DateTime.fromISO($json.body.data.submitted).setZone('Europe/Prague').toFormat('yyyy-MM-dd HH:mm') }}

Name

{{ $json.body.data.answers.find(a => a.question.id === 90403243)?.answer ?? "" }}

E-mail

{{ $json.body.data.answers.find(a => a.question.id === 90403263)?.answer ?? "" }}

Company

{{ $json.body.data.answers.find(a => a.question.id === 90403245)?.answer ?? "" }}

Team size

{{ $json.body.data.answers.find(a => a.question.id === 90403247)?.answer?.labels?.[0] ?? "" }}

What they want to see

{{ $json.body.data.answers.find(a => a.question.id === 90403244)?.answer ?? "" }}

Status

New (plain text, not an expression)

Language

{{ $json.body.data.langCode }}

Prepare lead node in n8n with Fields to Set

Save lead to sheet

  1. Add a Google Sheets node after Prepare lead, rename it to Save lead to sheet and choose the operation Append or Update Row.

  2. Connect your Google account, then pick your spreadsheet under Document and the leads tab under Sheet.

  3. Set Mapping Column Mode to Map Automatically and Column to match on to Response ID.

  4. Under Options, add Cell Format and choose Let n8n format. Otherwise Google Sheets turns answers like 2-10 into dates.

Save lead to sheet node: Append or Update Row, Map Automatically, Column to match on Response ID

Why a separate Prepare lead step? When you pick a different spreadsheet or tab in the Google Sheets node, n8n clears the column mapping inside that node. With the expressions in Prepare lead, nothing is lost.

E-mail the new lead

  1. Add a Gmail node after Save lead to sheet, rename it to E-mail the new lead, and choose Message and Send.

  2. Connect your Gmail account and put your own address in To.

  3. Set Subject to New demo request: {{ $('Prepare lead').item.json.Name }} ({{ $('Prepare lead').item.json.Company }}).

  4. Set Email Type to HTML and write the Message with the lead's details, for example {{ $('Prepare lead').item.json['E-mail'] }} for the e-mail address.

  5. Under Options, add Send Replies To with {{ $('Prepare lead').item.json['E-mail'] }}, so that Reply goes straight to the lead, and turn off Append n8n Attribution.

Gmail node E-mail the new lead with To, Subject, Message and Send Replies To

Click Publish again. Changes you make after publishing go live only when you publish again.

n8n workflow: Survio Webhook, Prepare lead, Save lead to sheet, E-mail the new lead

Submit another request. A new row with the status New appears in your sheet, and the e-mail from the top of this article arrives a moment later.

The leads tab in Google Sheets with a Status dropdown


​

Case B — Send every demo request to HubSpot

Here the lead goes straight into HubSpot CRM as a contact with the lifecycle stage Lead, so your sales team picks it up where they already work. The workflow has two steps after the webhook: Prepare lead and Create or update contact.

Prepare lead

Add an Edit Fields (Set) node after the Webhook node, rename it to Prepare lead, and add these String fields. Replace the question ids with your own.

Field name

Value

E-mail

{{ $json.body.data.answers.find(a => a.question.id === 90403263)?.answer ?? "" }}

First name

{{ ($json.body.data.answers.find(a => a.question.id === 90403243)?.answer ?? "").trim().split(" ")[0] }}

Last name

{{ ($json.body.data.answers.find(a => a.question.id === 90403243)?.answer ?? "").trim().split(" ").slice(1).join(" ") }}

Company

{{ $json.body.data.answers.find(a => a.question.id === 90403245)?.answer ?? "" }}

Message

Demo request from Survio. Team size: {{ $json.body.data.answers.find(a => a.question.id === 90403247)?.answer?.labels?.[0] }}. Wants to see: {{ $json.body.data.answers.find(a => a.question.id === 90403244)?.answer }}

The First name and Last name fields split the name from a single "Your name" question. If your form asks for first and last name separately, pick each answer by its own question id instead.
​

Create or update contact

  1. Add a HubSpot node after Prepare lead, rename it to Create or update contact, and choose the resource Contact and the operation Create or Update.

  2. Connect your HubSpot account.

  3. Set Email to {{ $json['E-mail'] }}. HubSpot uses the e-mail to find an existing contact, so a returning lead is updated instead of duplicated.

  4. Under Contact Properties, click Add Property and add First Name, Last Name, Company Name and Message with the matching fields from Prepare lead, and set Lifecycle Stage Name or ID to Lead.

HubSpot node Create or update contact with Email, contact properties and Lifecycle Stage Lead

Click Publish again.

n8n workflow: Survio Webhook, Prepare lead, Create or update contact

The contact may be linked to a company automatically. If HubSpot finds a company with the same e-mail domain, it associates the new contact with it, and the contact can take over that company's owner. That's usually what you want; check it once with a test request.

Get the ready-made workflow

Instead of building Step 3 and your case by hand, start from our workflow. Download the file for your case from the attachments at the end of this article: survio-demo-requests-to-sheet-and-gmail.json for Case A, or survio-demo-requests-to-hubspot.json for Case B. Then:

  1. In n8n, create an empty workflow. Open the menu (three dots) next to the workflow name and choose Import, then From file. Pick the file you downloaded.

  2. Open Prepare lead and replace the question ids with your own, and in Case A also Europe/Prague with your time zone.

  3. Case A: open Save lead to sheet. It shows a red warning sign until it's set up. Connect your Google account and pick your spreadsheet and its leads tab. n8n then switches Mapping Column Mode to Map Each Column Manually: set it back to Map Automatically and set Column to match on to Response ID. Then open E-mail the new lead, connect your Gmail account and put your own address in To.

  4. Case B: open Create or update contact and connect your HubSpot account.

  5. Open Survio Webhook, copy the Production URL into Survio (Step 4) and click Publish.

n8n workflow menu with Import and From file

Test it end to end

  1. Open your website, fill in the pop-up form and submit it.

  2. Case A: check that a row with the status New appears on the leads tab and that the e-mail arrives. Reply to it and check that the reply is addressed to the lead.

  3. Case B: open HubSpot and check that the contact is there with the lifecycle stage Lead and your demo request in its Message.

  4. Look at the Executions tab in n8n. Every delivery and its data are listed there.

Troubleshooting

Symptom

Cause

Fix

Nothing arrives in n8n

The Test URL is in Survio, or the workflow isn't published

Copy the Production URL into Survio and click Publish

Survio won't save the webhook URL from a self-hosted n8n

n8n shows an internal address instead of its public one

Set n8n's WEBHOOK_URL setting to your public https address and copy the URL again

"Listen for test event" shows nothing although the form was submitted

Survio sends to the Production URL; listening watches the Test URL

Check the Executions tab instead

Your latest change has no effect

The workflow is published, but the change isn't (the Publish button shows a dot)

Click Publish again

A column stays empty and a new column appears at the end of the sheet

A field name in Prepare lead doesn't match the column header exactly

Rename the field in Prepare lead to match the header, then delete the extra column

The same lead appears twice

Operation set to Append Row, or no column to match on

Use Append or Update Row and match on Response ID

Reply goes to you instead of the lead

Send Replies To isn't set in the Gmail node

Add Send Replies To under Options with the lead's e-mail

Team size shows as a date

Google Sheets reads 2-10 as a date

In Save lead to sheet, set Cell Format to Let n8n format

The e-mail address is missing

Read from data.email

Read it from the answer to your e-mail question

Create or update contact fails

The e-mail is empty or invalid, or the HubSpot connection has expired

Make the e-mail question required, and reconnect HubSpot in the node

Survio switched the webhook off

The webhook URL failed for 5 days in a row

Fix the cause, then switch the webhook back on in Survio

Good to know

  • Survio sends only completed responses, one message per response, within seconds. A form a visitor closes halfway isn't sent.

  • Nothing is sent retroactively: not responses from before the webhook existed, and not responses from while it was paused.

  • A failed delivery is retried up to 8 times over roughly 27 hours, and each attempt waits up to 30 seconds for a reply. Matching on Response ID keeps retries from adding duplicate rows.

  • If deliveries fail for 5 days in a row, Survio switches the webhook off and you need to switch it back on.

  • Pausing a webhook keeps its slot; deleting it is permanent.

  • Survio doesn't keep a delivery history in the app. The Executions tab in n8n is your log.

  • Sending responses to webhooks doesn't use up any extra responses from your plan.

Rather have us set it up? On the Webhooks page in Survio, click Get expert setup, tell us what you'd like to happen, and our team will build it, test it and hand you a working webhook.

Did this answer your question?