# Connect Airtable

> Know when a record starts matching a formula, or someone edits one, without keeping the base open. Read with a personal access token scoped to the bases you pick.

Source: https://coisland.app/docs/connect-airtable/

## What you need

- **You need:** Personal access token, from airtable.com › Create new token (https://airtable.com/create/tokens)
- **The form asks:** Connector name, Personal access token
- **You can watch:** Records, Changed records
- **Access:** GET requests only, with a token scoped to read records and schemas

To connect Airtable to CoIsland you need a personal access token you create yourself, with two read scopes and only the bases you want to watch. No OAuth integration, nothing to register. CoIsland calls Airtable's Web API straight from your Mac, keeps the token in your login Keychain, and only ever reads.

## Create an Airtable personal access token

1. Open `airtable.com/create/tokens` and select **Create new token**.
2. Name it, such as `CoIsland`.
3. Under **Scopes**, add `data.records:read` and `schema.bases:read`.
4. Under **Access**, add the bases (or a workspace) to watch.
5. Select **Create token** and copy it now: Airtable shows it only once.

Any Airtable user can create one, on every plan. Legacy API keys (starting with `key`) no longer work. On Enterprise, an admin can block API access to the organization's bases for everyone not on an allowlist.

## Connect Airtable in CoIsland

Open **Settings › Connectors**, click **+**, and choose **Airtable**.

| Field | What to enter |
|---|---|
| Connector name | What monitors call it: `airtable`. Letters, digits, `_` and `-`. |
| Personal access token | The token you created. |

**Test connector** calls `GET /v0/meta/whoami` and lists the bases the token reaches. It saves nothing, and says so if the token has no base yet or lacks `schema.bases:read`. The token is only ever sent to `https://api.airtable.com`, in the `Authorization` header.

## Choose what to watch: the two Airtable monitor kinds

The first line names the place, written by the editor's pickers: `base:`, `table:` and optionally `view:`. The lines after are a formula, as in a formula field or `filterByFormula`; none matches every record. A check reads up to 1,000 records.

### Records

A record alerts when it starts matching.

```text
base:appLkNDICXNqxSDhG table:tbltp8DGLhqbUmjK1 view:viwQpsuEDqHFqegkp
{Status} = 'Blocked'
```

### Changed records

A record alerts each time one of its fields is edited within `within:` (`1h`, `6h`, `24h` or `7d`; `24h` unless given). A formula, rollup or lookup recomputing is not an edit.

```text
base:appLkNDICXNqxSDhG table:tbltp8DGLhqbUmjK1 within:1h
```

## What an Airtable alert shows

The notch lists a record by its primary field, with `Tasks · Status: Blocked · Owner: Ana Lopez` under it. Clicking opens the alert in CoIsland, where the record fills in live: every field in the table's order, long text in full, and **Open in Airtable**.

## What an Airtable monitor's watch file looks like

```sql
-- name: Blocked records
-- kind: airtable.records
-- connector: airtable
-- alert: new-rows

base:appLkNDICXNqxSDhG table:tbltp8DGLhqbUmjK1
{Status} = 'Blocked'
```

The kinds are `airtable.records` and `airtable.changed`.

## Rate limits

Airtable allows 5 requests a second per base and 50 per token; after a 429 it asks for 30 seconds. A check costs one request for the table's schema and one per 100 records. When Airtable asks CoIsland to slow down, checks back off on their own.

## Troubleshooting Airtable connector errors

- **The token was refused.** Airtable answered 401: the token was deleted or regenerated.
- **… not allowed.** Airtable answered 403: the token lacks a scope, was not given this base, or your organization blocks personal tokens on its bases.
- **Airtable refused the request:** then Airtable's words, such as `Unknown field names` in a formula.
- **Table … no longer exists in Airtable, or the token was not given it.** Pick the table or view again.
- **That is a legacy API key.** Create a personal access token instead.
