# Airtable

Airtable is a cloud-based platform that combines the simplicity of a spreadsheet with the power of a database. The Sling Airtable connector automatically discovers all accessible bases and tables, creating a dynamic endpoint for each table.

{% hint style="success" %}
**CLI Pro Required**: APIs require a [CLI Pro token](https://docs.slingdata.io/sling-cli/cli-pro) or [Platform Plan](https://docs.slingdata.io/sling-platform/platform).
{% endhint %}

## Setup

The following credentials and inputs are accepted:

**Secrets:**

* `api_key` **(required)** -> Your Airtable Personal Access Token

**Inputs (optional):**

* `last_modified_field_map` (optional) -> A nested map of base names to table names to the field name containing the last modified timestamp. Used for incremental sync.

### Getting Your API Key

1. Go to [Airtable's token creation page](https://airtable.com/create/tokens)
2. Click "Create new token"
3. Give your token a name (e.g., "Sling Integration")
4. Add the following scopes:
   * `data.records:read` - To read records from tables
   * `schema.bases:read` - To discover bases and tables
5. Add access to the bases you want to sync (or all bases)
6. Click "Create token" and copy the token (it starts with `pat`)

### Using `sling conns`

Here are examples of setting a connection named `AIRTABLE`. We must provide the `type=api` property:

{% code overflow="wrap" %}

```bash
sling conns set AIRTABLE type=api spec=airtable secrets='{ api_key: patXXXXXXXXXXXXXX }'
```

{% endcode %}

### Environment Variable

See [here](https://docs.slingdata.io/sling-cli/environment#dot-env-file-.env.sling) to learn more about the `.env.sling` file.

{% code overflow="wrap" %}

```bash
export AIRTABLE='{ type: api, spec: airtable, secrets: { api_key: "patXXXXXXXXXXXXXX" } }'
```

{% endcode %}

### Sling Env File YAML

See [here](https://docs.slingdata.io/sling-cli/environment#sling-env-file-env.yaml) to learn more about the sling `env.yaml` file.

```yaml
connections:
  AIRTABLE:
    type: api
    spec: airtable
    secrets:
      api_key: "patXXXXXXXXXXXXXX"
```

**With incremental sync configuration:**

```yaml
connections:
  AIRTABLE:
    type: api
    spec: airtable
    secrets:
      api_key: "patXXXXXXXXXXXXXX"
    inputs:
      last_modified_field_map:
        'My Base Name':
          'My Table Name': 'Updated At'
        'Another Base':
          'Customers': 'Last Modified'
          'Orders': 'Modified Time'
```

## Replication

Here's an example replication configuration to sync Airtable tables to a PostgreSQL database:

```yaml
source: AIRTABLE
target: MY_POSTGRES

defaults:
  mode: full-refresh
  object: public.{stream_name}

streams:
  # sync all tables in all bases
  '*':

  # exclude a specific table
  sales_crm_contacts:
    disabled: True
```

This replication syncs all Airtable tables to PostgreSQL using full-refresh mode, except for `sales_crm_contacts` which is disabled.

## Dynamic Endpoints

The Airtable connector uses dynamic endpoint discovery. When you connect, Sling automatically:

1. Fetches all accessible bases
2. For each base, fetches all tables
3. Creates an endpoint for each table named `{base_name}_{table_name}` in snake\_case

For example, if you have a base called "Sales CRM" with tables "Contacts" and "Deals", Sling creates:

* `sales_crm_contacts`
* `sales_crm_deals`

To discover available endpoints:

```bash
sling conns discover AIRTABLE
```

Each record includes the following metadata fields in addition to your table columns:

* `_id` - The Airtable record ID
* `_created_time` - When the record was created
* `_base_id` - The Airtable base ID
* `_base_name` - The base name
* `_table_id` - The Airtable table ID
* `_table_name` - The table name

## Incremental Sync

To enable incremental sync for a table, you must specify which field contains the "last modified" timestamp using the `last_modified_field_map` input.

{% hint style="info" %}
Airtable does not have a built-in "last modified" field. You must create a "Last Modified" formula field in your Airtable table that tracks when records are updated.
{% endhint %}

**Example `env.yaml` with incremental sync:**

```yaml
connections:
  AIRTABLE:
    type: api
    spec: airtable
    secrets:
      api_key: "patXXXXXXXXXXXXXX"
    inputs:
      last_modified_field_map:
        'Data Catalog':
          'Datasets': 'Updated At'
```

**Example replication with incremental mode:**

```yaml
source: AIRTABLE
target: MY_POSTGRES

defaults:
  mode: incremental

streams:
  data_catalog_datasets:
    object: public.airtable_datasets
```

If you are facing issues connecting, please reach out to us at <support@slingdata.io>, on [discord](https://discord.gg/q5xtaSNDvp) or open a Github Issue [here](https://github.com/slingdata-io/sling-cli/issues).
