# Add Google Sheets Row

Append one row to a connected Google Sheet — the cheapest way to hand data from a conversation to a team that lives in a spreadsheet.

## Getting here

**Automate → Workflows**, open a workflow, click **+** on the canvas, then pick **Add Google Sheets Row** under **Add Steps**.

## Before you start

- An **owner**, **admin** or **agent** can add this step and save the workflow. Publishing that workflow — the thing that makes it run on live conversations — is an **owner** or **admin** action.
- Building and running workflows depends on your plan; see [pricing](/pricing).
- A Google account connected in **Settings → Integrations**, and the target spreadsheet shared with that account with edit access. Until connected, the drawer shows a connect card instead of the fields.

## Set up

1. Open the workflow and click **+** where the row belongs.
2. Pick **Add Google Sheets Row**.
3. Paste the spreadsheet's link and click **Load** — this reads its tabs and column headers, which only label the inputs below.
4. Pick the **Tab** if there is more than one.
5. Fill in **Row to add**, one field per column, with text or `{{…}}` placeholders.
6. Save the step, then publish the workflow.

## Fields

| Field | What it means | Limits |
| --- | --- | --- |
| Spreadsheet link | The sheet's own URL. Load fetches its tabs and column headers. | — |
| Tab | Which sheet tab to append the row to. | Only shown once Load has run. |
| Row to add | One value per column, labelled from the sheet's header row when known. | Columns are positional — the first value always goes to column A, the second to column B, and so on — whether or not a header was ever loaded. |

## How it works

- What leaves Inchat, and when: the instant the step runs, one call to the Google Sheets API appends a single row to the named tab, using this workspace's connected Google account. The values sent are exactly what you configured, with every `{{…}}` placeholder already resolved.
- The row is appended after whatever the sheet already has — it never overwrites or inserts in the middle.
- A value that starts with `=` is written as a formula, exactly as if it had been typed into the sheet by hand — Google's own write mode for this call treats input the same way a person typing into a cell would.
- Columns are positional on the wire: the header row shown in the drawer only labels which box maps to which column at the time you loaded it. If a column is reordered in the sheet afterwards, the step keeps writing to the same position, not the same header.

## When it fails

- Google Sheets is not connected for this workspace: the step fails with **Google Sheets is not connected — connect it in Settings › Integrations.**, before any request is sent.
- The connected account no longer has edit access to the sheet (never shared, or removed): Google answers 403 and the step fails with **That Google account cannot edit this spreadsheet — share the sheet with it, with edit access.**
- The spreadsheet id is wrong, deleted, or the connected account cannot see it: Google answers 404 and the step fails with **That spreadsheet does not exist, or the connected account cannot see it.**
- Google rejects a call made with a cached access token that Google itself already revoked (this workspace's stored expiry has not caught up yet): the step fails with **Google rejected the connection — reconnect Google Sheets in Settings.**, and Settings still shows Connected — reconnecting is on the operator, this path does not flip it to Disconnected on its own.
- Separately, when the stored token is due for its own routine refresh and that refresh call to Google fails (a genuinely revoked grant): the step fails with **Google Sheets is not connected — connect it in Settings › Integrations.**, and this time Settings is updated to show Disconnected, since the refresh failure is what the integration record acts on.
- Google is rate-limiting this workspace: the step fails with **Google Sheets is rate limiting this workspace — try again shortly.**
- A failed row does not stop the run: the step is recorded failed and the flow moves straight to the next one, and nothing is written to the sheet.

## Limits

- It publishes even with nothing connected. The connection card blocks editing the fields in the drawer, but not saving or publishing the workflow — a step left this way fails, once per run, every time it runs, until Google Sheets is connected.
- It only appends — it cannot update an existing row, look one up, or delete one.
- Column mapping is positional, not by header name — see How it works. Reordering the sheet's columns without editing this step silently misfiles the row.
- A row is capped at 50 values, each up to 4,000 characters.
- The connection is per workspace, not per sheet: anyone who can build a workflow here can point this step at any spreadsheet the connected Google account can edit, not only the one it was set up for.

## Use cases

- Log every completed order to a shared spreadsheet the fulfilment team already works from, right after **Move Deal to Stage** marks a deal won.
- Append a row for every lead that answers an **Ask a Question** step, so sales can work the list without opening Inchat.

## Related

- [HTTP Request](https://inchat.inseller.my/help/workflows/http-request)
- [Workflows: how a flow runs](https://inchat.inseller.my/help/workflows/workflows-overview)

---

Source files: `src/lib/workflows/ai-builder/spec.ts`, `src/lib/workflows/canvas-model.ts`, `src/components/workflows/WorkflowStepConfigDrawer.tsx`, `src/lib/workflows/partner-actions.ts`, `src/components/workflows/GoogleSheetsStepEditor.tsx`, `src/lib/integrations/google-sheets/client.ts`, `src/lib/workflows/connection-gates.ts`, `src/lib/workflows/engine-record-actions.ts`, `src/lib/workflows/workflow-input-schema.ts`
