> ## Documentation Index
> Fetch the complete documentation index at: https://docs.senderz.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Import from Google Sheets

> Pull contacts straight out of a Google spreadsheet, through the same mapping and consent flow as a file upload.

If your list already lives in a Google spreadsheet, you can import it without exporting a CSV first. You connect your Google account once, pick the spreadsheet, and Senderz reads it directly.

<Info>
  **Availability.** This is live end to end today: connect, pick a sheet,
  preview, map, and import all work. There is **no recurring sync**. Each
  import is a one-off read. If the sheet changes tomorrow, run the import
  again.
</Info>

## Where to find it

Google Sheets is not a card on the Integrations page. It appears as a second option next to the file uploader, everywhere you can start an import:

* **Contacts → Import**, on the Upload step.
* The Contacts empty state, when the workspace has no contacts yet.
* The **Create list** dialog, so the sheet imports straight into the new list.
* The **Import** step of onboarding.

The button reads **Import from Google Sheets**. If you do not see it anywhere, Google Sheets import has not been switched on for your workspace, and the dialog will say so. Everything else about importing is unaffected.

<Note>
  Starting an import needs an owner, admin, editor or designer seat. A viewer
  can see the Contacts screens but cannot connect Google or run an import.
</Note>

## The connection is yours, not the workspace's

This is the part that surprises people. The Google connection is tied to **your user account**, not shared with your teammates.

<Warning>
  If a colleague connected Google and imported a sheet last week, you still
  have to connect your own account before you can import. There is nothing to
  inherit. This is deliberate: a workspace-wide Google token would let any
  member browse whoever set it up their Google Drive.
</Warning>

Practical consequences:

* Each person who imports sheets connects once, on their own account.
* Disconnecting affects only you. Your colleagues keep their connections.
* The Google account shown in the dialog is the one the sheet will be read as. Pick the account that actually has the spreadsheet.

## Connecting

<Steps>
  <Step title="Open the dialog">
    Click **Import from Google Sheets** from any of the surfaces above.
  </Step>

  <Step title="Connect Google">
    Click **Connect Google**. A Google popup opens and asks which account to
    use, then asks you to approve access. Approving stores the connection
    against your user, so you will not be asked again on this account.
  </Step>

  <Step title="Choose a spreadsheet">
    Google's own file picker opens. Browse or search your Drive and select one
    spreadsheet. Only spreadsheets are selectable; folders and other file
    types are not.
  </Step>
</Steps>

If the popup is blocked, nothing happens when you click Connect. Allow popups for the Senderz app and click it again.

## Why there is no field to paste a sheet link

There is deliberately no "paste a Google Sheets URL" box, and adding one would not work.

Senderz asks Google for the narrowest permission available: access to **individual files you choose**, and nothing else. Under that permission, **the act of picking the file in Google's picker is what grants access to it.** A spreadsheet you have not picked is unreadable to Senderz even if you paste a perfect link to it, even if the link is public.

The alternative would be to ask you to set the sheet to "anyone with the link can view" so we could read it with a generic key. That means publishing a file of your customers' names, email addresses and phone numbers to anyone who guesses or forwards the URL. We are not asking you to do that with a customer list.

### What Senderz can and cannot see in your Drive

<CardGroup cols={2}>
  <Card title="Can see" icon="check">
    Only the spreadsheets you personally selected in the picker, and only to
    read them. Nothing is written back to the sheet.
  </Card>

  <Card title="Cannot see" icon="xmark">
    Any other file in your Drive. Senderz cannot list, search, open, edit or
    delete anything you did not pick, and cannot create files.
  </Card>
</CardGroup>

The picker is running on Google's side, not ours. When you scroll through your Drive in that window, Senderz does not receive any of it. Only the one file you click is handed over.

## Choosing the tab and the header row

Once a spreadsheet is picked, the dialog shows what it found:

<ParamField path="Sheet tab" type="dropdown">
  Only appears when the spreadsheet has more than one tab. Senderz starts on
  the first tab. Switching tabs re-reads immediately. **One tab imports per
  run.** To import three tabs, run three imports.
</ParamField>

<ParamField path="First row contains column names" type="toggle" default="on">
  On, the top row becomes your column names. Off, every row is treated as
  data and columns are named `Column A`, `Column B` and so on, which you then
  map by hand.
</ParamField>

<ParamField path="Columns found" type="preview">
  The first eight column names Senderz detected, plus a count. Use it to
  confirm you are looking at the right tab before continuing.
</ParamField>

You also get the row and column count, and a **Choose a different sheet** button if you picked the wrong file.

A few things about how the sheet is read:

* **Blank column headers get a placeholder name** based on the column letter, so an unlabelled column is still importable rather than silently dropped.
* **Duplicate headers are numbered.** Two columns both called `Email` become `Email` and `Email (2)`.
* **Trailing empty cells are fine.** Rows in a Google sheet are often ragged; Senderz sizes the table to the widest row, so a column that only has values further down is not lost.
* **Values arrive as they are displayed**, not as the underlying raw value. A date shown as `03/04/2024` imports as that text.

<Warning>
  That last point matters for **consent date** columns. Senderz only accepts
  ISO-style dates like `2024-04-03` for opt-in dates, because `03/04/2024`
  means March 4th to one exporter and April 3rd to another and nothing in the
  sheet says which. An unreadable consent date is not guessed at, it falls
  back to the import time. If the real opt-in date matters as consent
  evidence, format that column as `YYYY-MM-DD` in the sheet before importing.
</Warning>

Click **Continue to mapping** when the preview looks right.

## From there it is a normal import

A sheet joins the standard import wizard at the mapping step. Nothing about mapping, validation, duplicate handling or consent is special-cased for sheets:

<Steps>
  <Step title="Map fields">
    Senderz auto-maps recognisable column names and you confirm or change
    them. You can map a column to a new custom field from here, or set it to
    **Don't import this column**.
  </Step>

  <Step title="Existing contacts">
    Choose **Update existing**, **Skip updates** or **Add only new** for rows
    that match a contact you already have.
  </Step>

  <Step title="Review">
    A preview of what will import.
  </Step>

  <Step title="Subscription">
    The final step. Tick each channel these contacts actually gave you
    permission to market on, or leave it blank to keep the conservative
    default and rely on the sheet's own consent columns.
  </Step>
</Steps>

Three-stage email validation, the never-re-subscribe-an-opt-out rule, and the consent-log entry all behave exactly as described in [Importing contacts](/en/audience/import). Read that page for the rules; this page only covers what is different about the source.

<Note>
  Importing a sheet does **not** start any automation, however many contacts
  it creates. Bulk import never enrols people into flows.
</Note>

## The sheet is re-read when the import runs

The preview you approve is a look at the sheet, not a copy of it. When the import actually runs, Senderz reads the spreadsheet again.

That has two consequences worth knowing:

* **Edits you make between previewing and importing are picked up.** Spot a broken row on the review screen, fix it in Google Sheets, then start the import, and the corrected version is what imports.
* **The sheet has to still be reachable at that moment.** If you delete the spreadsheet, rename or delete the tab, or disconnect Google between clicking through the wizard and the import finishing, the import fails and tells you which of those happened.

<Warning>
  Because rows are re-read rather than snapshotted, **removing individual rows
  on the review screen is not available for a sheet import.** The row-level
  delete control you get with a CSV is hidden, because deleting a row there
  would have no effect on what actually imports. Delete the row in Google
  Sheets instead, then start the import.
</Warning>

## Limits

| Limit                            | Value                                                                           |
| -------------------------------- | ------------------------------------------------------------------------------- |
| Rows per import                  | 50,000. Past that the import stops and the status page reports it as truncated. |
| Tabs per import                  | One.                                                                            |
| Rows shown in the wizard preview | The first 100. The whole tab still imports.                                     |
| Recurring or scheduled sync      | Not available. Every import is a one-off.                                       |
| Writing back to the sheet        | Never. Access is read-only.                                                     |
| File size                        | Not applicable. Nothing is uploaded, so the 10 MB file limit does not apply.    |

A published-to-web link (the kind Google generates under **File → Share → Publish to web**) is a different kind of address that the Sheets API cannot resolve, so those are rejected. Pick the file through the picker instead.

## Tracking an import

Every sheet import appears on the import status page with live progress and a per-row results table, exactly like a file import. It is also listed on the **Import & export log** tab of Contacts, labelled **Google Sheets**, with the added, updated, skipped and rejected counts.

## Disconnecting

Open the Google Sheets dialog and click **Disconnect**. This removes the stored connection for your user and tells Google to revoke it.

You can also revoke it from Google's side, at [Google Account → Data & privacy → Third-party apps](https://myaccount.google.com/connections). Either way:

* Your teammates' connections are untouched.
* Contacts already imported stay. Disconnecting removes future access to your Drive, not the data you brought in.
* Any import still running fails, because it can no longer read the sheet.
* Reconnecting is the same three clicks as the first time. You will need to pick your spreadsheets again, since the permission is per file.

## Troubleshooting

<AccordionGroup>
  <Accordion title="I don't see the Import from Google Sheets button" icon="eye-slash">
    Google Sheets import is not switched on for your workspace. It is
    configured centrally, not per workspace setting, so there is nothing for
    you to enable. Contact support. CSV and Excel import are unaffected.
  </Accordion>

  <Accordion title="Google could not load the file picker" icon="triangle-exclamation">
    Usually a network or content blocker problem: the picker is loaded from
    Google's own servers. Retry, and if it persists check whether a browser
    extension or corporate network is blocking Google's script domains.
  </Accordion>

  <Accordion title="Google connection expired" icon="clock-rotate-left">
    The grant was revoked, either from your Google account's third-party
    access settings or by Google itself after long disuse. Click
    **Disconnect**, then **Connect Google** again, and re-pick the sheet.
  </Accordion>

  <Accordion title="Google denied access to that sheet" icon="shield-halved">
    The file was not selected through the picker for this app, or the grant
    for it lapsed. Opening it fine in your own browser does not mean Senderz
    can read it, that is exactly what the per-file permission is for. Choose
    the spreadsheet again through the picker.
  </Accordion>

  <Accordion title="That sheet is no longer available" icon="magnifying-glass">
    The spreadsheet or the tab was renamed, moved, or deleted between picking
    it and importing. Pick it again. Renaming a tab counts, since the tab is
    matched by name.
  </Accordion>

  <Accordion title="Google Sheets could not be reached" icon="cloud">
    Google was unreachable or rate-limiting when the import ran. This is
    almost always temporary. Start the import again in a few minutes.
  </Accordion>

  <Accordion title="The import ran but found no rows" icon="table-cells">
    The selected tab is empty, or every row sits above the header row you told
    Senderz to expect. Check you picked the right tab, and check the **First
    row contains column names** toggle matches the sheet.
  </Accordion>

  <Accordion title="Fewer contacts imported than rows in the sheet" icon="filter">
    Expected. Rows are rejected for invalid or undeliverable email addresses,
    duplicates within the file, and rows with neither an email nor a phone
    number. The status page lists a per-row reason for each and offers a
    **Download failed rows** file. See
    [Importing contacts](/en/audience/import) for the validation rules.
  </Accordion>
</AccordionGroup>

## Related

<CardGroup cols={2}>
  <Card title="Importing contacts" icon="file-import" href="/en/audience/import">
    Mapping, validation, duplicate handling and the consent rules that apply
    to every import source.
  </Card>

  <Card title="Consent and opt-in" icon="shield-check" href="/en/audience/consent">
    What counts as permission, and what the consent log records.
  </Card>
</CardGroup>
