Send form submissions to Google Sheets without Zapier
A spreadsheet is still the easiest CRM there is. This guide sends every submission from your website form into a Google Sheet as a new row, with no Zapier account and no per-task fees. It takes about ten minutes, and you only paste code once.
What you need: a Google account, and a FormRill form. Google Sheets is a Pro feature, free during the beta ($9/month after launch).
How it works
Google Sheets can’t receive data from a website on its own, but a tiny Google Apps Script attached to the sheet can. You publish that script as a “web app”, which gives it a private URL. FormRill sends each submission to that URL, and the script adds the row.
1. Create the sheet
Open a new Google Sheet and give it a name, such as “Website leads”. Leave it empty; the script writes the column headings for you.
2. Add the script
From the sheet’s menu, open Extensions → Apps Script. Delete whatever is in the editor and paste this:
// Adds one row per FormRill submission. New fields become new columns.
function doPost(e) {
const lock = LockService.getScriptLock()
lock.waitLock(10000) // two submissions at once won't overwrite each other
try {
const body = JSON.parse(e.postData.contents)
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0]
const row = {
submitted_at: new Date(body.created_at),
form: body.form_name,
...body.data,
}
const headers = sheet.getLastColumn()
? sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0]
: []
for (const key of Object.keys(row)) {
if (!headers.includes(key)) {
headers.push(key)
sheet.getRange(1, headers.length).setValue(key)
}
}
sheet.appendRow(headers.map((h) => row[h] ?? ''))
return ContentService.createTextOutput('ok')
} finally {
lock.releaseLock()
}
}Click Save.
3. Publish it as a web app
- Click Deploy → New deployment.
- Choose the type Web app.
- Set Execute as to yourself, and Who has access to Anyone. FormRill has no Google account, so it needs this to reach the script.
- Click Deploy and approve the permissions Google asks for. It’s your own script asking to edit your own sheet.
- Copy the Web app URL. It starts with
https://script.google.com/macros/s/and ends in/exec.
Keep that URL private: anyone with it can add rows to your sheet.
4. Connect it in FormRill
In your form’s Automations tab, choose Google Sheets, paste the web app URL and add it. Your email notifications keep working alongside it.
5. Test
Submit your form once. Within a few seconds the sheet gets a heading row and your first submission: when it arrived, the form name, then one column per field. A field you add to the form later simply becomes a new column.
Troubleshooting
- Nothing appears. Open the form’s Delivery log in FormRill. A failure there shows the status and error Google returned, and you’ll have had an email about it too. Fix the cause, then press Retry: the stored submission is sent again, so nothing is lost.
- You changed the script. Apps Script keeps serving the old version until you publish a new one: Deploy → Manage deployments, edit, and pick a new version. The URL stays the same.
- Rows land in the wrong tab. The script writes to the first tab. Drag the tab you want to the front, or change
getSheets()[0]togetSheetByName('Leads').
Why not Zapier?
Zapier and similar tools work, but they bill per task and add another account to the chain. Here the only moving parts are your form, FormRill and your own sheet, and a failed delivery is logged and retryable instead of disappearing into a task history.
Start sending submissions to Sheets
Free up to 500 submissions a month and unlimited forms. No server, no credit card.
Start freeRelated
- Form to Google Sheets
The integration at a glance.
- Form submissions to Slack or Discord
Another destination, same webhook payload.
- Webhook payload reference
The JSON the script receives.