> ## 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 Airtable data source in Adriel.

## Introduction

Airtable is a cloud database and spreadsheet platform where teams manage records in bases and tables. The Adriel Airtable connector imports the records of a single Airtable table into Adriel and makes that table's columns available as metrics and breakdowns in widgets. On a daily schedule, the connector re-reads the whole table through the Airtable REST API and replaces its cached copy, so widgets blend Airtable records alongside platform-native marketing data.

As a file/storage connector, the available fields are not a fixed catalog — they are derived from the schema of the imported table. Each column's Adriel data type is resolved from its Airtable field type; numeric columns become metrics, and all columns can serve as breakdowns. A typical use case is a marketing or operations team that keeps a campaign tracker, a creative inventory, or a partner contact list in Airtable and wants it on the same dashboard as its ad and analytics data.

To connect this data source, see [How to connect Airtable to Adriel](/data-sources/a-f/airtable/how-to-connect).

## Data refresh strategy

Airtable is a **scheduled-cache** connector. It does not query Airtable live on each dashboard load; instead it syncs the whole table once per day and serves widget queries from a cached copy.

**Refresh schedule (UTC).**

* Default: 8:00 AM daily.

On each refresh the entire selected table is re-read through the Airtable API and the cached copy is replaced atomically. Records deleted in Airtable disappear from Adriel after the next refresh, and columns renamed in Airtable propagate to the cache on the next refresh. Between refreshes, dashboards show the most recent cached snapshot rather than live Airtable data.

<Note>
  **Changes appear after the next daily sync**

  Because the cache is refreshed once per day, edits made in Airtable — new records, deletions, renamed columns, or changed values — are not reflected in Adriel until the next scheduled sync completes.
</Note>

## Architecture levels

Airtable workspace → Base → Table.

The connector discovers these levels through the Airtable metadata API:

1. **Workspace** — the Airtable workspace reached by the authorized connection.
2. **Base** — the bases granted during the OAuth consent step. Bases not authorized do not appear in the picker.
3. **Table** — the tables within the selected base.

One Adriel data source binds to one Airtable table, identified by a `baseId | tableId` composite key. Selecting several tables at setup creates one independent data source per table, all sharing the same connection.

## Date range limits

There is no platform-imposed date range limit. Date bounds are defined by the contents of the imported table. A table becomes date-filterable only when a date-type column is mapped as the date field during setup; without one, all rows are treated as a single snapshot set on the dashboard and are not filtered by the dashboard date range.

## Import model

The connection points at one Airtable workspace. The customer selects a base and then one or more tables; each selected table becomes a separate data source keyed by `baseId | tableId`.

The import runs in a fixed sequence:

1. **Schema discovery.** The connector reads the table schema through the Airtable metadata API and builds the field list from the table's columns, mapping each Airtable field type to an Adriel field type (see Field type mapping).
2. **Record fetch.** Records are read through the Airtable REST API (version `v0`) using offset-based pagination until the whole table has been retrieved.
3. **Cache replacement.** The full result is written to a per-data-source cache table in Adriel's Postgres store, atomically replacing the previous copy (`ATOMIC_REPLACE`).
4. **Widget queries.** When a widget loads, its query runs against the **Postgres cache**, not live against Airtable. This keeps widget loads fast and independent of Airtable API limits between refreshes.

Row queries against the cache are capped at **50,000 rows**. Because queries run against Postgres, widget filters use the full Postgres-compatible operator set rather than Airtable's own filter syntax.

## Filters

Widget filters are applied to the cached rows in Postgres. Date-range filtering depends on a date column being mapped during setup.

### Supported filter operators

Filter operators are sourced from the Postgres connector's operator set (`postgresFilterOperators`), so Airtable data sources support the full range of SQL-compatible filter conditions (equality, membership, comparison, and pattern matching) rather than a reduced whitelist.

### Date-range filtering

Date-range filtering is applied only when a date-type column (for example `date`, `dateTime`, `createdTime`, or `lastModifiedTime`) has been mapped as the date field during data-source setup. When no date column is mapped, the table is treated as a single snapshot and the dashboard date range does not filter it.

## Field type mapping

Airtable has no fixed metric or breakdown catalog. The available fields are the columns of the imported table, typed at ingestion from the Airtable field type using a static lookup (`airtableTypeToDataSourceFieldType`).

<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**. Numeric columns can serve as metrics or breakdowns; all other columns serve as breakdowns.
</Note>

Each Airtable field type maps to an Adriel field type as follows.

| Airtable field type                                                                    | Adriel field type | Data type      | Import handling                                                                                                                                                     |
| -------------------------------------------------------------------------------------- | ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `number`, `currency`, `percent`, `duration`, `count`, `autoNumber`, `rating`           | `number`          | Number         | Value passed through as-is                                                                                                                                          |
| `singleLineText`, `multilineText`, `email`, `url`, `phoneNumber`, `richText`, `aiText` | `string`          | Text           | Value passed through as-is                                                                                                                                          |
| `singleSelect`                                                                         | `string`          | Text           | Selected option value                                                                                                                                               |
| `multipleSelects`                                                                      | `string`          | Text           | Values joined with a pipe separator                                                                                                                                 |
| `date`, `dateTime`, `createdTime`, `lastModifiedTime`                                  | `string`          | Text           | Passed through as a string (see note); map as the date field to enable date-range filtering                                                                         |
| `checkbox`                                                                             | `string`          | Text           | Passed through as a string                                                                                                                                          |
| `singleCollaborator`                                                                   | `string`          | Text           | Collaborator name                                                                                                                                                   |
| `multipleCollaborators`                                                                | `string`          | Text           | First collaborator's name only                                                                                                                                      |
| `createdBy`, `lastModifiedBy`                                                          | `string`          | Text           | User name                                                                                                                                                           |
| `multipleRecordLinks`                                                                  | `string`          | Text           | Linked-record values joined with a pipe separator                                                                                                                   |
| `multipleLookupValues`                                                                 | `string`          | Text           | Values joined with a pipe separator                                                                                                                                 |
| `multipleAttachments`                                                                  | `string`          | Text           | First attachment's URL only                                                                                                                                         |
| `barcode`                                                                              | `string`          | Text           | Barcode text                                                                                                                                                        |
| `formula`, `rollup`, `lookup`, `externalSyncSource`                                    | `any`             | Number or Text | Type resolved from the actual value at row level; no schema-level override (`rollup` uses the first element's name; `externalSyncSource` is serialized to a string) |
| `button`                                                                               | —                 | —              | Always empty at parse time; excluded from the field list                                                                                                            |

<Note>
  **Date columns are imported as text**

  Date, date-time, created-time, and last-modified-time columns are imported as text values, not as a native Date data type. Date-range filtering still works, but only when one of these columns is mapped as the date field during setup.
</Note>

### Adriel-added fields

Adriel injects two synthetic fields on top of the table's own columns, regardless of table content. Internal metadata columns (`id`, `created_at`, `updated_at`, `filename`, `file_updated_at`) are filtered out and never exposed as selectable fields.

| Field     | Role      | Description                                                                | Data type | Default aggregation |
| --------- | --------- | -------------------------------------------------------------------------- | --------- | ------------------- |
| Row count | Metric    | Number of rows in the imported table (or in the widget-filtered subset).   | Number    | Sum                 |
| Raw data  | Breakdown | The raw record payload, available as a breakdown for detail-level display. | Text      | Unique              |

### Aggregation defaults

When no explicit aggregation is set on a field, the connector chooses one based on the field's role and type.

| Field                                                                                          | Default aggregation |
| ---------------------------------------------------------------------------------------------- | ------------------- |
| Numeric columns (`number`, `currency`, `percent`, `duration`, `count`, `autoNumber`, `rating`) | Sum                 |
| Text columns (used as breakdowns)                                                              | Unique              |
| Row count (synthetic metric)                                                                   | Sum                 |
| Raw data (synthetic breakdown)                                                                 | Unique              |

## Limitations

Based on the current connector:

* **Daily refresh only.** Data is synced once per day; there is no live or on-demand refresh. Edits in Airtable appear only after the next scheduled sync.
* **Snapshot replacement.** Each refresh replaces the entire cached table. Records deleted in Airtable are removed from Adriel after the next refresh; the connector does not track deletions mid-cycle.
* **50,000-row query cap.** Row queries against the cache are capped at 50,000 rows.
* **One table per data source.** Each table becomes its own data source. Multi-table joins are not supported natively; combine tables in Airtable first, or use Blend Data settings.
* **Generic data source.** Airtable data can be viewed in a generic table and combined with other connectors only when it shares the same breakdowns; otherwise Blend Data settings are required.
* **Date columns are text.** Date, date-time, created-time, and last-modified-time columns import as text. Date-range filtering requires mapping a date column during setup; without one, the table is a single snapshot.
* **`formula`, `rollup`, `lookup`, and `externalSyncSource` are untyped at the schema level.** These resolve to `any` and are typed from the row value, so their metric/breakdown behavior can vary. `rollup` exposes only the first element's name.
* **Partial multi-value fields.** `multipleAttachments` exposes only the first attachment's URL, and `multipleCollaborators` only the first collaborator's name. `multipleSelects`, `multipleRecordLinks`, and `multipleLookupValues` are joined into a single pipe-separated text value.
* **`button` fields are dropped.** Button columns always parse to empty and are excluded from the field list.
* **Per-base OAuth scoping.** Only bases granted during the OAuth consent step are available. Adding a new base requires reconnecting.
* **Refresh-token expiry disconnects the data source.** Airtable refresh tokens have a long but finite lifetime; when one expires, the next sync fails and the data source enters a disconnected state. Reconnecting issues a fresh token — see the paired how-to.

## API references

* [Airtable Web API introduction](https://airtable.com/developers/web/api/introduction)
* [Airtable OAuth reference](https://airtable.com/developers/web/api/oauth-reference)
* [List records](https://airtable.com/developers/web/api/list-records)
* [Get base schema (metadata API)](https://airtable.com/developers/web/api/get-base-schema)
* [Field types and cell values](https://airtable.com/developers/web/api/field-model)

## See also

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