# Google Sheets

> Log leads, unanswered questions, feedback, and demo requests straight to a Google Sheet with a one-click AI Action. No Zapier, no webhooks, no code.

Connect your AI Agent to Google Sheets so the useful moments in a conversation, a qualified lead, a question it couldn't answer, a feature request, a demo ask, become rows in a sheet your team already uses. There's no Zapier, no webhook, and no code: the connection is one click, and what it creates is a normal [AI Action](/ai-agent/actions/#custom-actions) you can edit.

## How it works

An AI Action is a described HTTP request, and a Google Sheet row is one such request. Google Sheets has an `append` endpoint that adds a row to a tab; each report is a `POST` to that endpoint with the row values in the body.

![How a Google Sheets logging action is built: a description that says when to call it, the parameters the Agent fills from the chat, and the request it sends](https://docs.quickchat.ai/_astro/how-it-works.CCIkdKZH.png)

A few things worth knowing up front:

- **The columns aren't fixed.** They're whatever the Action sends. You decide them by editing the Action's request body and the sheet's header row, so the same integration can log leads, bug reports, or anything else.
- **Least-privilege access.** The Google connection requests only the `drive.file` scope, which grants access exclusively to files the integration creates. It can't see the rest of your Drive.
- **The AI never sees your credentials.** The request carries an `Authorization` header set to the placeholder `{{google_sheets_access_token}}`. Quickchat fills it with a real, auto-refreshed token after the model has done its part; the token never enters the prompt.

## Connect Google Sheets

Open **Actions & MCPs** in the sidebar, click **Add Action**, and choose **Google Sheets**.

![The Add Action menu with the Google Sheets option](https://docs.quickchat.ai/_astro/connect-menu.DnMMW1or.png)

The connect dialog explains what the one click will set up before you grant any access: a new Google Sheet in your Drive, and a ready-to-use logging action, preset for leads. Click **Connect**, choose the Google account whose Drive the sheet should live in, and approve the `drive.file` permission.

![The connected Google Sheets dialog, explaining the sheet and starter action are ready](https://docs.quickchat.ai/_astro/connect-dialog.CqgTMVxg.png)

That one click does two things automatically:

1. **Creates a spreadsheet** in your Google Drive, with a `Leads` tab and a header row.
2. **Adds a single, disabled AI Action** (`log_lead_to_google_sheet`), already wired to that sheet.

:::note
If you ever delete the starter action, open **Add Action → Google Sheets** again and use **Reconnect**: it re-creates the action and reuses your existing sheet rather than making a second one.
:::

## The generated logging action

The starter action is a normal, fully editable [API Action](/ai-agent/actions/#create-an-api-action). It's listed under **Custom Actions**, switched off, so you can review it before enabling it.

![The starter lead action's name and the parameters the Agent fills in from the conversation](https://docs.quickchat.ai/_astro/lead-action-config.dH0oizN7.png)

Because Quickchat created the sheet and the action together, the endpoint URL already contains your spreadsheet's ID:

```
https://sheets.googleapis.com/v4/spreadsheets/<your sheet ID>/values/Leads:append?valueInputOption=RAW
```

Keep `valueInputOption=RAW` so a message starting with `=` or `+` is stored literally rather than parsed as a formula. The headers are the same for every report:

| Key | Value |
|---|---|
| `Authorization` | `Bearer {{google_sheets_access_token}}` |
| `Content-Type` | `application/json` |

The request **body** is a single row, and each cell is one parameter. The cells run in the same order as the sheet's columns:

```json
{ "values": [["{{email}}", "{{what_they_asked}}", "{{conversation_url}}", "{{conversation_channel}}"]] }
```

So the columns are defined by this body plus the tab's header row, not hardcoded by the integration. `{{conversation_url}}` (a deep link back to the Inbox) and `{{conversation_channel}}` (where the visitor came from) are [built-in variables](/ai-agent/variables/#built-in-variables) available to any Action.

Review the parameters and the **description** (the description is what the AI reads to decide when to log a row), then switch the action on.

## Log anything, not just leads

To add another report, give your sheet a new tab and add another API Action that appends to it. Copy the full URL from the lead action and change only the tab name, then adjust the parameters, body, and description:

```
https://sheets.googleapis.com/v4/spreadsheets/<your sheet ID>/values/Unanswered:append?valueInputOption=RAW
```

Common reports teams build alongside leads:

| Report | When the Agent writes a row |
|---|---|
| Unanswered questions | The Agent can't answer a factual question, the visitor asks for a human, or seems unsatisfied |
| Feedback | A visitor requests a feature, reports a bug, or gives praise |
| Demo requests | A visitor explicitly asks for a demo, a call, or to talk to sales |

![A captured lead written straight into the Leads tab of the sheet](https://docs.quickchat.ai/_astro/sheet-leads.D204-fpy.png)

:::tip
Add columns by adding parameters to the body and matching headers in the sheet. Use `{{metadata_*}}` to log anything already on the conversation. See [AI Action Variables](/ai-agent/variables/) for the full list.
:::

## Frequently asked questions

**Do I need Zapier, a webhook, or any code?**
No. Quickchat connects to Google Sheets directly through an AI Action, a native HTTP request the Agent makes during the conversation. One click creates the sheet and the first logging action for you.

**Is my Google Drive data safe?**
Yes. The integration requests only the `drive.file` OAuth scope, which grants access exclusively to files it creates, such as the sheet it makes for you. It can't read or change anything else in your Drive, and the access token is never exposed to the AI model.

**Which channels does it work on?**
All of them. The same Actions run wherever your Agent is deployed (web widget, Slack, WhatsApp, and more), and the `{{conversation_channel}}` column records where each row came from.

## Related

- [Custom Actions](/ai-agent/actions/#custom-actions): how AI Actions work and how to edit one.
- [AI Action Variables](/ai-agent/variables/): the `{{...}}` placeholders you can put in a row.
- [Connect your AI Agent to Google Sheets](https://quickchat.ai/post/connect-ai-agent-to-google-sheets): a full, worked tutorial that builds all four reports and tunes them.
