How to Send Form Submissions to Google Sheets
Send every form submission to Google Sheets automatically. Connect Google once and each entry lands as a new row — plus a free webhook + Apps Script method.
The ShipMyForm team
· 5 min read
A Google Sheet is still the fastest place to collect form responses. Everyone on the team can read it, you can sort and filter without learning a tool, and it drops straight into a chart or a pivot table. The hard part is the plumbing between a form on a static site and the sheet, because a plain HTML form has no way to write to Google on its own.
There are two clean ways to bridge that gap with ShipMyForm, and this guide covers both: the managed Google Sheets connector, which creates the sheet and appends rows for you after a single Google sign-in, and a free do-it-yourself route using the webhook connector and a short Google Apps Script. Pick whichever fits your plan and how much you want to maintain.
The two approaches at a glance
| Managed connector | Webhook + Apps Script | |
|---|---|---|
| Setup | Connect Google once, done | Paste a script, deploy it |
| Sheet | Created for you automatically | You create it |
| Plan | Paid (Starter and up) | Free plan works |
| Maintenance | None | You own the script |
| Best for | Get it working in a minute | Free tier or full control |
Both rely on ShipMyForm sitting in front of your form: it catches the POST, stores the submission, and filters spam before anything reaches your sheet — so your spreadsheet stays clean instead of filling up with bot noise.
Option A: the managed Google Sheets connector
This is the one-click path. You connect a Google account, ShipMyForm creates a spreadsheet in your Drive, and every submission from then on lands as a new row.
Step 1: point your form at ShipMyForm
Your form stays plain HTML. Set its action to your form endpoint — no JavaScript
required:
<form action="https://shipmyform.com/f/YOUR_FORM_ID" method="POST">
<input name="name" required />
<input name="email" type="email" required />
<textarea name="message" required></textarea>
<button type="submit">Send</button>
</form>Step 2: add the Google Sheets connector
In your dashboard, open the form, go to Connectors, and add Google Sheets. You will be sent through Google's sign-in, where you grant offline access so ShipMyForm can keep writing to the sheet after you close the tab.
Google has to hand back a refresh token for the connection to work. If you untick the offline-access prompt, the connector cannot write later and will ask you to reconnect. If that happens, just run the connect step again and approve it.
Step 3: your sheet is created automatically
As soon as you finish connecting, ShipMyForm creates a new spreadsheet in your
Drive named after the form, for example ShipMyForm: Contact form, with a tab
called Submissions. There is no spreadsheet ID to copy and no template to set
up — the link to the sheet appears in the connector settings.
The first submission defines the columns. ShipMyForm writes a header row made
of a Submitted at timestamp followed by your form's field names, then appends the
values:
| Submitted at | name | message | |
|---|---|---|---|
| 2026-07-23T10:32:00.000Z | Jane Doe | [email protected] | Loved the guide! |
Every later submission is appended as a new row, lined up under those same columns.
The connection uses Google’s drive.file scope, which only grants
access to files the app creates. ShipMyForm can write to the one sheet it made
for you and nothing else in your Drive — it never sees your other documents.
Handling fields you add later
Because the header is fixed from the first submission, a field you add to the form
afterwards will not create its own column on its own. When you add a field, add a
matching header cell to the sheet (the exact field name), and new submissions
will start filling it. Values with no matching column are left out of the row
rather than shifting everything sideways, so your columns never drift.
That is the whole managed setup. From here the sheet is yours — sort it, chart it, or connect it to anything else that reads Google Sheets.
Option B: free, with the webhook connector and Apps Script
On the free plan, or if you want to own the integration end to end, you can send submissions to a sheet yourself. Google Apps Script can turn any spreadsheet into a tiny web endpoint, and ShipMyForm's free webhook connector posts each submission to it.
Step 1: create the sheet and open Apps Script
Make a new Google Sheet. In the menu choose Extensions → Apps Script and replace the default code with this:
function doPost(e) {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const body = JSON.parse(e.postData.contents);
const data = body.data || {};
// Create a header row from the first submission's fields.
if (sheet.getLastRow() === 0) {
sheet.appendRow(["Submitted at", ...Object.keys(data)]);
}
const header = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
const row = header.map((col) =>
col === "Submitted at" ? body.submittedAt : (data[col] ?? ""),
);
sheet.appendRow(row);
return ContentService.createTextOutput("ok");
}Step 2: deploy it as a web app
In Apps Script, choose Deploy → New deployment → Web app. Set Execute as
yourself and Who has access to Anyone, then deploy and copy the
/exec web app URL.
Step 3: point the webhook connector at it
In your ShipMyForm form, open Connectors, add the Webhook connector (it is
on the free plan), paste the /exec URL, and save. Send a test — a new row should
appear in your sheet.
Every webhook delivery carries an X-ShipMyForm-Signature header:
sha256= followed by an HMAC-SHA256 of the raw body, keyed with the
connector’s signing secret. Since an Apps Script web app is open to the
internet, recompute that hash with Utilities.computeHmacSha256Signature
and reject anything that does not match before you append the row.
The trade-off is ownership: this route is free and fully in your control, but the script is yours to maintain, and Apps Script has its own quotas on a busy form. The managed connector exists precisely so you do not have to think about any of that.
Which one should you use?
- Just want it working, and you are on a paid plan? Use the managed connector. It creates the sheet, handles auth refresh, and appends rows with zero code.
- On the free plan, or you want the data to flow through your own script? Use the webhook + Apps Script route.
Either way, ShipMyForm's storage means every submission is also kept in your dashboard, so even if a sheet write fails you still have a durable copy — nothing is lost.
Next steps
- New to this? Start with what a form backend actually is.
- Want submissions in your inbox too? See how to send an HTML form to your email.
- Need branching logic or many destinations? Connect your form to n8n.
- Start free — email and the webhook connector are on every plan, with 100 submissions a month and no card required.
Frequently asked questions
- Do I have to create the spreadsheet myself?
- No. When you connect your Google account, ShipMyForm creates a new spreadsheet in your Drive named after your form (for example "ShipMyForm: Contact form") with a tab called Submissions. You never paste a spreadsheet ID or set up anything by hand.
- Can ShipMyForm see my other Google Drive files?
- No. The connection uses Google's drive.file scope, which limits access to files the app itself creates. ShipMyForm can read and write only the one spreadsheet it made for your form — it cannot see or touch anything else in your Drive.
- Is the Google Sheets connector free?
- The managed Google Sheets connector is on ShipMyForm's paid plans (Starter and up). If you are on the free plan, you can still get submissions into a sheet using the free webhook connector plus a short Google Apps Script — that method is covered below.
- What happens when I add a new field to my form later?
- The header row is created once, from your first submission's fields, with a "Submitted at" column in front. Each later submission is aligned to that header, so if you add a new field, add a matching column header to the sheet and new submissions will start filling it. Fields that have no matching column are simply left out of the row.
Related guides
How to Connect Your Form to n8n
Send every form submission straight into an n8n workflow with the free webhook connector. No serverless glue, no polling.
What Is a Form Backend? (And When You Need One)
The plain-language definition, how form endpoints work, and when a hosted backend beats rolling your own.
How to Send an HTML Form to Your Email (Without a Backend)
Why mailto: and PHP mail() let you down on a static site — and the reliable way to get form submissions into your inbox, spam folder avoided.