Google Sheets forms: send responses to a spreadsheet
Every response becomes a row, as it arrives. Connect Google once, then create a sheet or pick one you already use.
Google Sheets delivery needs Basic or Advanced
How do I connect a form to Google Sheets?
- In the form editor, open Settings → Storage, choose Google Sheets, and sign in with your Google account. The app requests
drive.fileandsheetsscopes only. - You can then create a new sheet (it will be named after the form and placed in your Drive root), or pick an existing one from the Google Picker. The picker lets you search and browse — you cannot paste a sheet ID.
- Once a sheet is selected, press Check connection. It verifies that the sheet is readable and the first row contains header text. The check succeeds even if the columns are empty; the headers are what matter.
- If you added new questions after the sheet was created, press Create missing columns to add them to the sheet.
Understanding the column map
Columns in a Google Sheet are positional — they have no ID like a Notion property or a persistent name match like an Airtable field. So the app stores sheetHeaderMap, which links each question to the text in the sheet’s header row. When a response arrives, the app reads the sheet’s headers live, finds each column’s current position, and writes the answer there.
This design has a practical consequence: if you rename a question in the form, the sheet still has the same header and nothing breaks. If you rename a column in the sheet, the app can no longer find a header with that text, so the answer is skipped rather than misrouted. If you reorder the columns in the sheet — moving columns around, sorting, or hiding and unhiding — the answer goes to whichever column now holds the matching header.
Column positions are cached for five minutes
Adding new questions later
If a question is added to the form AFTER the sheet is connected, there is no column for it yet. When a response with the new question is submitted, that answer is skipped during delivery and logged as “no matching column.”
To deliver the new question, open the destination settings and press Create missing columns. This reads your sheet, finds all questions with no mapped column, and adds a new one at the right edge of the table for each, named after the question. The operation happens only when you explicitly press the button — delivery never modifies a sheet on its own. A respondent pressing Submit must not be able to change your schema.
After the columns are added, save the form. The new map is stored on the destination, and new responses will deliver to the new columns.
What gets written, and when
One row per submission, appended at the bottom of the sheet as it arrives. Each answer goes into the column matching its question’s header text. Delivery is attempted once with a timeout and there are no retries — Google Sheets is a destination, not the record. Every response is stored in your dashboard first, so a sheet that is unreachable or rate-limited cannot cost you an answer.
The app uses the insertDataOption=INSERT_ROWS parameter, which ensures that new rows are inserted rather than overwriting existing data below the table. Formulas in your sheet are never executed during write — the API uses RAW_VALUES mode, not USER_ENTERED, so the sheet treats everything as plain text.
Why is my row not appearing in the sheet?
| What you see | What to do |
|---|---|
| A response arrived in the dashboard, but not in the sheet | The question label does not match any header in your sheet. Open the destination settings and check the column names and their order. Press Create missing columns to add columns for unmatched questions, then press Resync missing rows to deliver the response. |
| An answer is in the wrong column | This happens when a question is added before its column is created. The row was already written to the wrong place. Rename a column header to match the question, then press Resync missing rows to redeliver only the missing rows. (Resync does not move rows already written.) |
| Rate limited (429) | Google Sheets has a quota and the row was NOT written. The response is safe in your dashboard. Wait for the quota window to close, then press Resync missing rows. |
| Timeout | The sheet did not respond in time. The response is safe in the dashboard. Press Resync missing rows to try again. |
| 401 Unauthorized or 403 Forbidden | Your Google token may have expired or been revoked. Press the Sign in link in the destination settings and re-authorize the app. |
| Sheet not found (404) | The sheet was deleted. Create a new one or pick an existing one through the Google Picker and save. |
| Nothing at all | Check the form is on a paid plan — connected apps are skipped on free, while everything else about the submission carries on as normal. |
Can I send to Google Sheets and somewhere else at once?
Yes. Destinations are independent and delivered in parallel, and one failing never affects another or the submission itself. Every response is stored in your dashboard regardless. If Google Sheets succeeds and Slack fails, both will be logged, and you can retry Slack separately.
Common questions
- Why can I rename a question and the delivery still works?
- Questions are bound to columns by their HEADER TEXT through a stored map called sheetHeaderMap. When a response is delivered, the app reads the sheet's header row live and looks up each column's current INDEX — so if you rename a question in the form, the sheet still has the same header and nothing breaks. If you rename the header in the sheet itself, the delivery will still try to match the question label, find no column with that text, and skip that answer. But if you reorder the columns in the sheet, each column's position updates in the live read and the answer goes to the right place.
- What happens if I add a new question to the form?
- When a respondent presses Submit, their answers are written to columns that already exist. A new question has no column yet, so that answer is skipped in the delivery and named in the log. To deliver new questions, open the destination settings and press Create missing columns. That operation reads your sheet, finds questions with no mapped column, and adds a new column for each one — named after the question and placed at the right edge. It only runs when you press the button: delivery never edits the sheet on its own, because a respondent pressing Submit must not be able to change your schema.
- Why can't I see or search the rest of my Google Drive?
- The app requests the `drive.file` OAuth scope, which grants access ONLY to files we created for you or files you explicitly pick through the Google Picker. You cannot paste a sheet ID and link it directly — you must use the picker to choose an existing sheet. This is intentional: it prevents the app from ever reading files you do not want it to see, and it limits the damage if a token is compromised.
- Why does an answer starting with = appear with a leading apostrophe?
- A value starting with = is a formula in spreadsheets. If we wrote it directly, it would execute as a formula when someone opens the sheet, or when they export to CSV and open it in Excel. Instead, the app prefixes answers that start with = (or +, -, or @), or with a tab or line break, with an apostrophe, which tells the spreadsheet application to treat the value as plain text. You see the apostrophe in the cell formula bar but not in the cell itself — the cell displays the actual answer.
- What does the Resync button fix?
- Every response in your dashboard has a unique Response ID. When you press Resync missing rows, the app backfills up to 500 of the most recent rows that are missing from your sheet by comparing the Response ID column. Large forms may need Resync pressed more than once to backfill all missing rows. Re-running Resync is always safe because it never writes a row twice — it diffs on the Response ID column. Resync rebuilds delivery failures caused by network timeouts or rate limits. It does NOT repair a row that was already written to the wrong columns — if a question was not yet mapped when a response was delivered, the answers ended up in the wrong place and Resync cannot move them.
- What happens if a delivery fails because Google is rate-limiting me?
- The row is not written to the sheet, but the response is still safe in your dashboard. Google Sheets has a quota, and a busy form can exceed it. The response waits with the log marked "rate limited". Press Resync missing rows after the quota window closes, and the row will be delivered then. Nothing is lost.