Skip to main content

Using Webhook with Typeform and Google Spreadsheet

You have textual explanations and a video for each step

1. A blank Spell to start and analyze incoming data

First, you'll need to create a new blank Spell. Each Spell has a unique URL and this URL will be the destination of a webhook.

Open the Payload and clear it (leave an empty JSON object: {}).

We'll now log the content of the params variable to know what is coming from the webhook.


The params variable is always set inside your Spell.

This variable contains anything sent to your Spell, using query parameters inside the URL. You can also call your Spell URL with the POST method and the params variable will contain the body of your request.

For example, if you add these parameters &firstName=Harry&lastName=Potter to a Spell URL (ex:, your params variable will contain:

firstName: "Harry",
lastname: "Potter"

Finally, go to the Versions tab, click on dev environment and copy the URL with the default API key using the dedicated button.

Video demo

2. Set up the webhook on Typeform and test it

We use Typeform for the purpose of this video.

Go on your Typeform, then on the Connect menu. Click on the Webhook tab and create a new webhook.

You can paste your Spell URL here.

Set your webhook delivery to On and go to the View deliveries menu.

Click on Send test request to send a request on your Spell.

On the next menu, you can see the payload send to your Spell and the Response should be 200. If not, check your Spell URL and retry.

Go back and on your Spell and click on the Console menu: you should see inside a log entry the content of Typeform's payload.

Video demo

3. Process Typeform data from webhook

Let's process the data in order to extract all responses each time a webhook is sent.

To make this process easier, you can copy and paste the payload from Typeform inside your own payload. That will let you test your code each time you need it.

You can now work the way you want to process your data (you have to use here your JS skills).

Video demo

4. Using Google Spreadsheet as a connector

We have now the answers we want. We'll use Google Spreadsheet connector to append a new line each time we receive a new answer from Typeform.

First, we'll create a new Google Spreadsheet and set the headers for our table.

Use the left menu to Add a new connector, choose Google Spreadsheet and the append endpoint.

We can use the One-click authentication to connect our Google account to Meta API.


You can also configure your own OAuth 2 account manually if you want to control all settings and if you later want to release a Google OAuth window with your own logo and application name for your end-users.

We will configure the spreadsheetId, the range and the valueInputOption.


The A1 notation for Google Spreadsheet is detailed in their documentation

Inside our code, we'll configure the values variables inside our connector's body, which is getting an array of array.

Video demo

5. Push on production and live test

Since our tests are working fine, time to deploy our Spell and test it in production!

Go on Versions menu, click on Create a new version and promote it to production.

Copy the new URL of your Spell.


The difference between your Spell in development or in production is done by the URL parameter &dev=true inside the URL.

You can easily use this parameter if you want to switch between environments.

Then, update your existing webhook or add a new webhook on the Typeform interface.

You can clean your Google Spreadsheet from your test values.

Open the URL of your Typeform and answer it.

Then, go on your Google Spreadsheet, and you'll see a new line.

Typeform is now connected to Google Spreadsheet through your own Spell!

If you go back to your Spell's detail page, you'll see a new line in your logs interface with all information you choose to log inside.

Video demo


The code

Here is the full code used inside our demo. You can easily replace the Google Spreadsheet connector part with a new connector from your interface.

const { form_response } = params;


const finalAnswer = {};

for (const answer of form_response.answers) {
const field = form_response.definition.fields.find(
(f) => ===

if (!field) {
console.error("Unable to find the target field");

let response;

switch (answer.type) {
case "choice":
response = answer.choice.label;
case "text":
response = answer.text;
console.error("Unable to process this kind of answer");

finalAnswer[field.title] = response;

console.log({ finalAnswer });

//#region Start of Google Spreadsheet connector
const googleSpreadsheetResult: Datapostvspreadsheetsspreadsheetidvaluesrangeappend =
await connectorService.config("626d1955b77971e210ec8a1a", {
body: {
values: [
finalAnswer["Question 1"],
finalAnswer["Question 2"],
});{ "Google Spreadsheet": googleSpreadsheetResult });
//#endregion End of Google Spreadsheet connector