Client intake form to Google Sheets: a review workflow that holds up
Sending a client intake form to Google Sheets takes a few minutes. Turning those rows into a queue your team can actually work from takes a little design: a tab the integration owns, a tab your reviewers own, dropdowns for status and owner, and a handful of formulas. This guide builds that workflow step by step, with formulas written for the way Zunoform actually writes rows.
By Raj Kumar, Founder, Zunoform

Short answer
Connect the intake form to Google Sheets so each submission lands as a row on a Responses tab, then never edit that tab. Add a Review tab keyed by Response ID where your team records status, owner, next action and due date using dropdowns, a Queue tab that uses FILTER to show submissions nobody has triaged yet, and a small dashboard built with COUNTIFS and QUERY. Share the file as Restricted and keep passwords and payment details out of the form entirely.
- Responses tab: integration-managed, append-only, never sorted or edited.
- Review tab: one row per Response ID, with status and owner dropdowns.
- Queue tab: =FILTER of Response IDs not yet in Review.
- Dashboard: COUNTIFS for workload and overdue items; QUERY for each person's list.
What arrives in the sheet when a client submits the intake form?
With Zunoform's native connection, authorizing Google Sheets creates a new spreadsheet named after the form with a tab called Responses. Each new completed response is appended as one row. The columns are:
| Column | What it holds | What to know for formulas |
|---|---|---|
| Timestamp | Submission time as ISO text in UTC, for example 2026-09-28T14:03:11.000Z | Stored as text, not a date. Convert it before sorting or comparing dates. |
| Response ID | Zunoform's unique ID for the submission | Your join key. Every review record points back to it. |
| One column per question | Answers in form order, headed by the question label | Multi-part fields split: a contact field becomes several columns such as email and phone; an address becomes its lines. |
| Location | Approximate location, when collected | Empty for forms in anonymous mode. |
| User Agent | The respondent's browser string | Rarely useful for review; hide the column. |
Values are written with the Sheets API RAW option, so they are stored exactly as submitted: a budget of 5000 arrives as the text 5000, not a number. Answers beginning with =, +, - or @ get a leading apostrophe so Sheets never runs them as formulas. Checked in Zunoform's code on 28 September 2026.
Sources: Google Sheets API: ValueInputOption (RAW) · Zunoform: Google Sheets integration
Three things the connection does not do
It does not backfill: only responses completed after you connect and enable it are sent, and partial responses are not sent. Earlier responses can be exported as CSV from the dashboard. It does not let you pick an existing spreadsheet; it creates one. And if you rename or reorder questions, the header row is rewritten to the new labels while older rows keep their old positions, so freeze the question list before you start collecting real intakes.
How should you lay out the spreadsheet?
Four tabs, each with one owner. The split is what keeps the integration and your team from overwriting each other.
| Tab | Who writes to it | Contents | Rule |
|---|---|---|---|
| Responses | The integration only | One row per submission | Never sort, insert columns, add formulas or type in it. |
| Queue | Formula only | Response IDs not yet triaged | Read-only view; All triaged means nothing is waiting. |
| Review | Your team | One row per Response ID with status, owner, next action, due date | The only place people type. |
| Lists | Account lead | Allowed statuses and owner names | Source for the dropdowns; edit here, not in the rule. |
An optional fifth tab, Dashboard, holds the COUNTIFS and QUERY summaries. Keep it formula-only.
Sources: Google Sheets: FILTER function
Which columns belong on the Review tab?
Column letters below are used in every formula in this guide. Add columns to the right if you need more.
Scroll sideways to read all three columns.
| Column | Type | Purpose |
|---|---|---|
| A: Response ID | Pasted as value from Queue | Join key back to Responses. |
| B: Received | Formula | Timestamp converted to a real date-time. |
| C: Client | Formula | Organization name looked up from Responses. |
| D: Status | Dropdown from Lists | New, Needs info, In review, Qualified, Declined, Done. |
| E: Owner | Dropdown from Lists | One named person, never a team. |
| F: Next action | Free text | A verb and an object: Ask for brand files, Book kickoff. |
| G: Due | Date (validated) | When the next action is due. |
| H: Repeat client? | Formula | Flags a second submission from the same email. |
How do you set up the status and owner dropdowns?
Put the allowed values on the Lists tab so changing a status name is one edit, not a rule rebuild.
Fill the Lists tab
Type statuses in Lists!A2:A7 (New, Needs info, In review, Qualified, Declined, Done) and owner names in Lists!B2:B6.
Create the Status rule
Select Review!D2:D. Open Data > Data validation, add a rule, choose Dropdown (from a range) and enter =Lists!A2:A7.
Reject bad input
Leave invalid data set to Reject the input, which is Google's default. Show a warning lets people type values that break your COUNTIFS totals.
Repeat for Owner
Select Review!E2:E and create the same kind of rule pointing at =Lists!B2:B6.
Validate the Due column
Select Review!G2:G and add a rule with the criteria Is valid date, so overdue formulas compare real dates rather than text.
Which formulas make the queue work?
Queue!A2 (untriaged Response IDs): =IFERROR(FILTER(Responses!B2:B, Responses!B2:B<>"", COUNTIF(Review!A2:A, Responses!B2:B)=0), "All triaged") Review!B2 (Received, as a date-time in UTC; format the column as Date time): =LET(ts, XLOOKUP(A2, Responses!B:B, Responses!A:A, ""), IF(ts="", "", DATEVALUE(LEFT(ts,10))+TIMEVALUE(MID(ts,12,8)))) Review!C2 (Client; replace D with the column holding your organization question): =XLOOKUP(A2, Responses!B:B, Responses!D:D, "missing") Review!H2 (repeat submissions; replace E with your email column): =IF(A2="", "", COUNTIF(Responses!E:E, XLOOKUP(A2, Responses!B:B, Responses!E:E, ""))>1) Numeric answers arrive as text. Wrap them before doing maths, for example: =VALUE(XLOOKUP(A2, Responses!B:B, Responses!F:F, "0"))
Fill B2, C2 and H2 down the Review tab. Column letters on Responses depend on your form's question order, so check them against the header row first.
Why the Queue uses copy-and-paste instead of a live link
It is tempting to make Review!A2 a FILTER formula that pulls every Response ID automatically. Do not. A formula column cannot be sorted together with the typed columns next to it, so the first time someone sorts Review by due date, statuses end up beside the wrong clients. Instead, the triager copies new IDs from Queue and uses Paste special > Values only into the next empty Review row. Each ID drops off Queue as soon as it exists in Review, which gives you a simple rule: triage is done when Queue says All triaged (IFERROR catches the error FILTER returns when nothing matches).
The Received formula converts the ISO text into a real date-time. DATEVALUE reads the first ten characters (the date) and TIMEVALUE reads characters 12 to 19 (the time). The result is UTC, so if your team works in another time zone, add or subtract the offset as a fraction of a day, for example -5/24.
How do you build a dashboard with COUNTIFS and QUERY?
Dashboard!B2 (open items for the owner named in A2; fill down beside each owner): =COUNTIFS(Review!$E:$E, A2, Review!$D:$D, "<>Done", Review!$D:$D, "<>Declined") Dashboard!C2 (overdue items for that owner): =COUNTIFS(Review!$E:$E, A2, Review!$G:$G, "<"&TODAY(), Review!$D:$D, "<>Done", Review!$D:$D, "<>Declined") Dashboard!E2 (one person's open list, earliest due first): =QUERY(Review!A1:G, "select A, C, D, F, G where E = 'Priya' and D <> 'Done' and D <> 'Declined' order by G asc", 1) Dashboard!F2 (triaged submissions received in the last 7 days): =COUNTIFS(Review!$B:$B, ">="&(NOW()-7))
In QUERY, items with an empty due date sort to the top in ascending order; treat that as a prompt to add one. Priya is an illustrative name.
Conditional formatting that reviewers notice
Select Review!A2:H, open Format > Conditional formatting, choose Custom formula is and enter =AND($G2<>"", $G2<TODAY(), $D2<>"Done") with a red fill. Overdue rows now stand out without anyone running a filter. Add a second rule, =$D2="Needs info" with amber, for items waiting on the client.
Conditional formatting formulas can only reference the same sheet directly; other tabs need INDIRECT. That is why the repeat-client check lives in its own Review column (H) and the formatting rule reads =$H2=TRUE, rather than reaching into Responses from inside the rule.
One more caveat from Google's QUERY documentation: when a column mixes data types, the majority type wins and the rest are treated as empty. Because RAW values arrive as text, run QUERY on the Review tab, where B and G hold real dates, rather than directly on Responses.
Source: Google Sheets: Conditional formatting
Source: Google Sheets: QUERY function
Who should have access, and how do you protect client data?
The spreadsheet is created in the Google account that authorized the connection, and that account owns it. Authorize with an agency-controlled account, not a contractor's personal Gmail, so ownership does not leave with a person. Set general access to Restricted. Give Editor only to the people who triage; everyone else gets Viewer or Commenter.
Google lets owners stop editors from changing permissions or sharing, and stop viewers and commenters from downloading, printing or copying. Turn both on for intake data. Protected ranges (Data > Protect sheets and ranges) are useful to stop accidental edits on Responses, but Google says plainly that protection is not a security measure: anyone with access can still copy or export the data.
PII hygiene checklist for an intake sheet
- The form never asks for passwords, recovery codes, API keys or card numbers; it asks who can grant access.
- General access is Restricted, and link sharing is off.
- Editors cannot change sharing; viewers cannot download or copy.
- Responses is protected so only the owner can edit it.
- Location and User Agent columns are hidden, or the form uses anonymous mode if you do not need them.
- Declined and completed intakes are exported and removed on a fixed schedule that matches your privacy notice.
- Access is reviewed when someone leaves the team.
What should you do when a row is missing or looks wrong?
Scroll sideways to read all three columns.
| Symptom | Likely cause | What to do |
|---|---|---|
| A submission is in Zunoform but not in the sheet | Integration disabled, authorization expired, or a delivery still retrying | Check the connected card, then search Responses for the Response ID before adding anything by hand. |
| The same Response ID appears twice | A manual recovery followed by a successful retry | Delete the manual copy; keep the one the integration wrote. |
| Header labels no longer match older rows | Questions were renamed or reordered mid-collection | Freeze the form, or start a new form version and a new sheet. |
| Numbers will not add up | Values are stored as text | Wrap them in VALUE() or convert the column on the Review tab. |
| An answer shows a leading apostrophe | It began with =, +, - or @ and was guarded against formula injection | Expected. Leave it; it is text. |
Where Zunoform fits (and where it doesn't)
The Google Sheets integration is included on Zunoform's free plan, along with Zoho CRM, Zapier catch hooks and webhooks. Agency intake templates such as the Website Design Questionnaire, the SEO Client Onboarding Questionnaire and the Paid Advertising Client Intake are ready to connect. The free plan allows 500 responses a month; Google Forms, Tally and Youform offer unlimited free responses, and Google Forms can also link to an existing spreadsheet, which Zunoform's connection cannot do today.
Zunoform writes the rows. The Review tab, dropdowns, formulas and sharing settings in this guide are things you set up in Google Sheets yourself; the integration does not assign owners, set statuses or send reminders. If you need a full CRM pipeline, Zoho CRM on free or HubSpot on Pro are better homes for qualified leads than a spreadsheet.
Intake templates that work with this sheet
Define a website's goals, page scope, content ownership and launch requirements before design begins.
Align target markets, organic goals, CMS ownership and reporting expectations before SEO delivery starts.
Scope campaign objectives, media budget, landing pages and conversion ownership before buying ads.
Describe recurring creative demand, typical work size, review capacity and budget before discussing a retainer.
Questions people ask
How do I send a client intake form to Google Sheets?
In Zunoform, save the form, open its Integrations tab and authorize Google Sheets. Zunoform creates a spreadsheet named after the form with a Responses tab, and each new completed submission is appended as a row. Submit a test response through the saved form and check the row before sharing the form with clients.
Can I connect the form to an existing spreadsheet?
Not with Zunoform's native connection today; it creates a new spreadsheet. You can add your own Review, Queue and Lists tabs to that spreadsheet, and use formulas to pull data into another file with IMPORTRANGE if your team already has a master tracker.
Why won't my number answers add up in Google Sheets?
Zunoform writes values exactly as submitted, so numbers arrive as text. SUM and COUNTIFS comparisons ignore text numbers. Wrap them in VALUE(), for example =VALUE(F2), or convert them on a separate Review tab so the integration-managed Responses tab stays untouched.
Can I add status columns next to the responses?
Avoid it. The integration rewrites the header row when your questions change and appends rows across the columns it writes, so hand-typed columns beside Responses can be overwritten or misaligned. Keep status, owner and notes on a separate Review tab keyed by Response ID.
Will old intake responses appear in the sheet?
No. Only responses completed after the integration is connected and enabled are sent, and partial responses are not. Export earlier responses as CSV from the Zunoform dashboard and paste them in as a one-off, checking Response IDs for duplicates.
Is it safe to keep client intake data in Google Sheets?
It can be, with care. Keep general access Restricted, limit editors, stop viewers downloading or copying, and never collect passwords or card numbers in the form. Protected ranges prevent accidental edits but are not a security control. Remove old intakes on a schedule that matches your privacy notice.
Is the Zunoform Google Sheets integration free?
Yes. Google Sheets is available on the free plan, which includes 500 responses a month, with no card required. Pro adds integrations such as Slack, Notion, HubSpot, Airtable and Excel.
Raj Kumar · Founder, Zunoform
Raj Kumar is the founder of Zunoform, the form builder made by Symphonic Grow. He builds the product and writes these guides, checking every competitor price and feature claim against the vendor's own pages before publishing.
Raj Kumar on LinkedInKeep reading
Integration setup
Agency operations
Agency workflow
Agency operations
Agency operations

Ready when you are
Better forms.
Better data.
Start with a conversation, a document or a single page.
Unlimited forms and 500 responses per month on Free.
No card required.
- No credit card
- Unlimited forms
- 500 responses / month