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

# Data reference

> Import model, field type mapping, refresh cadence, and limits for the Google Sheets data source in Adriel.

## Introduction

Google Sheets is Google's cloud spreadsheet product. The Adriel Google Sheets connector imports the rows of one tab of one spreadsheet through the Google Sheets API and caches them in a dedicated table per data source, so dashboards reflect the latest values without any manual re-upload. It is the most common file-based connector — used for manually maintained conversion targets, shared budget tables, and partner-maintained performance sheets.

As a file/storage connector, the available fields are not a fixed catalog — they are the columns of the chosen tab, read from its first (header) row. Every non-empty header becomes a field that can serve as either a metric or a breakdown; data types are inferred from the imported column values. Because the fields track the sheet, adding, removing, or renaming a column changes the available fields after the next refresh.

To connect this data source, see [How to connect Google Sheets to Adriel](/data-sources/g-n/google-sheets/how-to-connect).

## Data refresh strategy

Google Sheets is a cached connector. Each data source has its own cache table, and every refresh re-fetches the full contents of the tab and replaces the cache.

**Schedule (UTC).** The default refresh runs on the cron `0 */4 * * *` — every 4 hours, on the hour. Manual refresh is available from the data-source settings.

**Atomic replacement.** Each refresh writes rows to a temporary table first, then atomically swaps it in (`ATOMIC_REPLACE`). There is no append or upsert path, so a failed sync leaves the previous snapshot intact rather than a half-loaded table, and rows deleted from the sheet disappear from dashboards only after the next successful refresh.

**Field metadata cache.** The available-field metadata is cached with a 12-hour TTL. Columns added, removed, or renamed on the sheet become visible after this cache and the next data refresh update.

## Architecture levels

Spreadsheet → Tab.

The connection points at one tab of one Google Sheets file:

1. **Spreadsheet** — the file identified by the spreadsheet ID parsed from its URL.
2. **Tab** — one sheet within that file, chosen from a dynamically fetched list.

One Adriel data source binds to one tab, identified by the asset ID `{spreadsheetId}/{sheetId}`. To import a second tab, create a second data source. The same Google authorization covers every spreadsheet and tab the authorizing account can read.

## Date range limits

There is no platform-imposed date range limit. Date bounds come from the sheet contents through a date column that is mapped during data-source setup, which enables date-range filtering on the dashboard. A tab without a mapped date column is treated as a single snapshot set with no time-based breakdown.

## Import model

The connector reads through the Google Sheets API and caches the result; there is no per-widget SQL. One import proceeds as follows.

1. **URL validation.** The customer pastes the full Sheets URL. It must contain `https://docs.google.com/spreadsheets/d/`; otherwise it is rejected synchronously with `Link is invalid. Please input the full link of your spreadsheet.` before any API call.
2. **Spreadsheet and tab selection.** The spreadsheet ID is parsed from the path segment after `/d/`, the file's tabs are listed, and the chosen tab becomes the data source (asset ID `{spreadsheetId}/{sheetId}`).
3. **Header parsing.** The first row of the tab is treated as the header. Every non-empty header cell becomes a field. Empty headers become `column_<N>` (1-based); duplicate headers are de-duplicated with ` (2)`, ` (3)` suffixes.
4. **Value read.** Cell values are read as displayed, so the sheet's cell formatting (number, date, percentage) influences how each column is typed. Column types are then derived from the cached table (see Field type mapping).

Column headers are also sanitized for safe storage. The public header shown in widget builders is preserved where possible, while the stored column name has disallowed characters stripped, reserved internal names suffixed with `_column`, remaining collisions suffixed with `_2`, `_3`, and names longer than 63 bytes truncated at a character boundary with a 12-character hash suffix. A stored mapping translates field names, breakdowns, filter conditions, sort fields, and the date-field setting between the public header and the stored column transparently at query time.

<Note>
  **Google Sheets format only**

  Values are read through the Google Sheets API in their Sheets form. XLSX, ODS, and other spreadsheet formats are not supported through this connector; a file imported into Google Sheets is read as a Google Sheet.
</Note>

<Note>
  **Renaming a tab is handled automatically**

  If the selected tab is renamed on the Google side, the connector relinks to it on the next fetch rather than disconnecting. Deleting the tab, by contrast, disconnects the data source.
</Note>

## Filters

Widget filters translate from the public header names to the stored column names through the connector's column map before they run against the cache, including nested `AND` / `OR` conditions. Date-range filtering is applied to the column mapped as the date field during data-source setup; a tab with no mapped date column has no date-range filter and is treated as a single snapshot set.

## Field type mapping

Google Sheets has no fixed metric or breakdown catalog. The available fields are the columns of the chosen tab, and each field is usable as either a metric or a breakdown (`metric_or_breakdown`). Data types are derived from the cached column types after each sync (FieldsVersion 3), which in turn follow the values read as-displayed from the sheet.

<Note>
  **How to read the columns**

  The **Data type** column uses the platform's ten-value vocabulary: **Number**, **Currency**, **Percentage**, **Ratio**, **Duration**, **Date**, **Text**, **URL**, **Array**, **Boolean**. The **Field role** column indicates whether the field can serve as a metric, a breakdown, or both.
</Note>

Each parsed column type maps to an Adriel field type as follows.

| Parsed column type                                                   | Adriel field type | Data type | Field role                                                                  |
| -------------------------------------------------------------------- | ----------------- | --------- | --------------------------------------------------------------------------- |
| Numeric (integer or decimal)                                         | `number`          | Number    | Metric or breakdown (defaults to metric)                                    |
| Boolean (`TRUE` / `FALSE`)                                           | `boolean`         | Boolean   | Metric or breakdown                                                         |
| Date or timestamp                                                    | `date`            | Date      | Metric or breakdown; used for date-range filtering when mapped during setup |
| Text, or any value that does not parse as a number, boolean, or date | `string`          | Text      | Metric or breakdown (defaults to breakdown)                                 |

Because typing follows the displayed value, a numeric column that contains any non-numeric cell is imported as text. Numbers formatted as currency or percentage in the sheet are read as their displayed strings unless they parse cleanly as numbers.

### Adriel-added fields

The connector exposes no synthetic fields on top of the sheet's own columns. Internal bookkeeping columns written to the cache table — `created_at`, `updated_at`, `file_updated_at`, `filename`, `primary_key`, and `rowCount` — are excluded from the field metadata returned to widget builders. Columns removed from the sheet are cleaned up from the field metadata on the next sync.

### Aggregation defaults

Fields imported as numbers are aggregated by summing when used as metrics; fields imported as text, date, or boolean are intended as breakdowns and are grouped rather than aggregated. An explicit aggregation set on a field in the widget overrides this default. *(Inference from the metric/breakdown split; not confirmed against a connector-specific aggregation table — flag for tech review.)*

## Limitations

Based on the current connector:

* **One tab per data source.** Each data source imports a single tab; additional tabs require additional data sources (the same authorization covers them).
* **Google Sheets format only.** XLSX, ODS, and other formats are not supported; the file must be a Google Sheet.
* **50 MB file limit.** Spreadsheets above this size are not supported by the connector.
* **Standard Sheets URL required.** The link must contain `https://docs.google.com/spreadsheets/d/`; shortened or pre-edit URLs are rejected on entry.
* **Refresh latency up to 4 hours.** Between scheduled refreshes (every 4 hours) dashboards show the last cached snapshot; use a manual refresh to pull the latest values sooner.
* **Deletions and renames lag one refresh.** Rows deleted in the sheet remain until the next successful refresh; renamed columns update the corresponding field only after the next refresh.
* **Columns may be renamed on import.** Headers are sanitized for storage — special characters stripped, reserved names suffixed, duplicates de-duplicated, and over-long names truncated with a hash suffix — though the public header is preserved in widget builders where possible.
* **No raw-data breakdown.** The generic raw-data view is not supported (`rawData` disabled); widgets must use the discovered column fields directly.
* **Read-only by default.** The default authorization is read-only; write scope is requested only when export back to a sheet (Datastream) is enabled.
* **Auto-disconnect on tab, permission, or auth loss.** The data source disconnects when the tab is deleted or not found (`GSS_INVALID_SHEET_NAME`), when the caller loses permission, or when the Google authorization is revoked or expired (`invalid_grant`, `invalid_scope`, `Token has been expired or revoked.`, `admin_policy_enforced`) — see the paired how-to for re-authorization steps.

## API references

* [Google Sheets API overview](https://developers.google.com/sheets/api)
* [Sheets API v4 reference](https://developers.google.com/sheets/api/reference/rest)
* [Google OAuth 2.0](https://developers.google.com/identity/protocols/oauth2)
* [OAuth 2.0 scopes for Google APIs](https://developers.google.com/identity/protocols/oauth2/scopes#sheets)

## See also

* [How to connect Google Sheets](/data-sources/g-n/google-sheets/how-to-connect) (paired how-to)
* [Airtable data reference](/data-sources/a-f/airtable/data-reference) — alternative structured-data platform
* [Notion data reference](/data-sources/g-n/notion/data-reference) — alternative document/database source
