# Airtable (/integrations/airtable)





{/* MANUAL-CONTENT-START:intro */}

Use [Airtable](https://airtable.com/) to list bases and table schemas, read or write records, and start workflows from record changes. For token setup, see [Personal Access Tokens](/integrations/airtable-service-account).

Trigger mode handles record creation, updates, and deletion. Inspect `payloads` or `latestPayload` for Airtable's raw changes; deleted record IDs are under `changedTablesById[tableId].destroyedRecordIds`. The `airtableChanges` array currently consolidates created and updated records and returns changed cell values in `changedFields`.

{/* MANUAL-CONTENT-END */}

Connection guides: [Personal access tokens](/integrations/airtable-service-account).

## OAuth scopes [#oauth-scopes]

Sim requests these scopes when someone connects an Airtable account. For a self-hosted deployment, register your own app with the provider using the settings below. See [Integrations and OAuth](/platform/self-hosting/integrations-oauth) for setup.

| Setting | Value |
| - | - |
| Redirect URI | `<NEXT_PUBLIC_APP_URL>/api/auth/oauth2/callback/airtable` |
| Environment variables | `AIRTABLE_CLIENT_ID`, `AIRTABLE_CLIENT_SECRET` |

| Scope | Description |
| - | - |
| `data.records:read` | Read records |
| `data.records:write` | Create, edit, and delete records |
| `schema.bases:read` | View bases and tables |
| `user.email:read` | Read email address |
| `webhook:manage` | Create, view, and delete base webhooks and read their payloads |

## Use the block [#usage-instructions]

List bases, list tables (with schema), and create, get, list, update, upsert, or delete records. Use trigger mode to start a workflow when a record is created, updated, or deleted in an Airtable table.

## Actions [#actions]

### Airtable List Bases [#airtable-list-bases]

List all bases the authenticated user has access to

<ReferenceDetails>
  #### Input [#input]

  | Parameter | Type | Required | Description |
  | - | - | - | - |
  | `offset` | string | No | Pagination offset for retrieving additional bases |

  #### Output [#output]

  | Parameter | Type | Description |
  | - | - | - |
  | `bases` | array | Array of Airtable bases with id, name, and permissionLevel |
  | ↳ `id` | string | Base ID (starts with "app") |
  | ↳ `name` | string | Base name |
  | ↳ `permissionLevel` | string | Permission level (none, read, comment, edit, create) |
  | `metadata` | json | Pagination and count metadata |
  | ↳ `offset` | string | Offset for next page of results |
  | ↳ `totalBases` | number | Number of bases returned |
</ReferenceDetails>

### Airtable List Tables [#airtable-list-tables]

List all tables and their schema in an Airtable base

<ReferenceDetails>
  #### Input [#input-1]

  | Parameter | Type | Required | Description |
  | - | - | - | - |
  | `baseId` | string | Yes | Airtable base ID (starts with "app", e.g., "appXXXXXXXXXXXXXX") |

  #### Output [#output-1]

  | Parameter | Type | Description |
  | - | - | - |
  | `tables` | array | List of tables in the base with their schema |
  | ↳ `id` | string | Table ID (starts with "tbl") |
  | ↳ `name` | string | Table name |
  | ↳ `description` | string | Table description |
  | ↳ `primaryFieldId` | string | ID of the primary field |
  | ↳ `fields` | array | List of fields in the table |
  | ↳ `id` | string | Field ID (starts with "fld") |
  | ↳ `name` | string | Field name |
  | ↳ `type` | string | Field type (singleLineText, multilineText, number, checkbox, singleSelect, multipleSelects, date, dateTime, attachment, linkedRecord, etc.) |
  | ↳ `description` | string | Field description |
  | ↳ `options` | json | Field-specific options (choices, etc.) |
  | `metadata` | json | Base info and count metadata |
  | ↳ `baseId` | string | The base ID queried |
  | ↳ `totalTables` | number | Number of tables in the base |
</ReferenceDetails>

### Airtable List Records [#airtable-list-records]

Read records from an Airtable table

<ReferenceDetails>
  #### Input [#input-2]

  | Parameter | Type | Required | Description |
  | - | - | - | - |
  | `baseId` | string | Yes | Airtable base ID (starts with "app", e.g., "appXXXXXXXXXXXXXX") |
  | `tableId` | string | Yes | Table ID (starts with "tbl") or table name |
  | `maxRecords` | number | No | Maximum number of records to return (default: all records) |
  | `filterFormula` | string | No | Formula to filter records (e.g., "(\{Field Name} = 'Value')") |

  #### Output [#output-2]

  | Parameter | Type | Description |
  | - | - | - |
  | `records` | array | Array of retrieved Airtable records |
  | ↳ `id` | string | Record ID |
  | ↳ `createdTime` | string | Record creation timestamp |
  | ↳ `fields` | json | Record field values |
  | `metadata` | json | Operation metadata including pagination offset and total records count |
  | ↳ `offset` | string | Pagination offset for next page |
  | ↳ `totalRecords` | number | Number of records returned |
</ReferenceDetails>

### Airtable Get Record [#airtable-get-record]

Retrieve a single record from an Airtable table by its ID

<ReferenceDetails>
  #### Input [#input-3]

  | Parameter | Type | Required | Description |
  | - | - | - | - |
  | `baseId` | string | Yes | Airtable base ID (starts with "app", e.g., "appXXXXXXXXXXXXXX") |
  | `tableId` | string | Yes | Table ID (starts with "tbl") or table name |
  | `recordId` | string | Yes | Record ID to retrieve (starts with "rec", e.g., "recXXXXXXXXXXXXXX") |

  #### Output [#output-3]

  | Parameter | Type | Description |
  | - | - | - |
  | `record` | json | Retrieved Airtable record |
  | ↳ `id` | string | Record ID |
  | ↳ `createdTime` | string | Record creation timestamp |
  | ↳ `fields` | json | Record field values |
  | `metadata` | json | Operation metadata |
  | ↳ `recordCount` | number | Number of records returned (always 1) |
</ReferenceDetails>

### Airtable Create Records [#airtable-create-records]

Write new records to an Airtable table

<ReferenceDetails>
  #### Input [#input-4]

  | Parameter | Type | Required | Description |
  | - | - | - | - |
  | `baseId` | string | Yes | Airtable base ID (starts with "app", e.g., "appXXXXXXXXXXXXXX") |
  | `tableId` | string | Yes | Table ID (starts with "tbl") or table name |
  | `records` | json | Yes | Array of records to create, each with a `fields` object |
  | `typecast` | boolean | No | When true, Airtable automatically converts string values to the field type |

  #### Output [#output-4]

  | Parameter | Type | Description |
  | - | - | - |
  | `records` | array | Array of created Airtable records |
  | ↳ `id` | string | Record ID |
  | ↳ `createdTime` | string | Record creation timestamp |
  | ↳ `fields` | json | Record field values |
  | `metadata` | json | Operation metadata |
  | ↳ `recordCount` | number | Number of records created |
</ReferenceDetails>

### Airtable Update Record [#airtable-update-record]

Update an existing record in an Airtable table by ID

<ReferenceDetails>
  #### Input [#input-5]

  | Parameter | Type | Required | Description |
  | - | - | - | - |
  | `baseId` | string | Yes | Airtable base ID (starts with "app", e.g., "appXXXXXXXXXXXXXX") |
  | `tableId` | string | Yes | Table ID (starts with "tbl") or table name |
  | `recordId` | string | Yes | Record ID to update (starts with "rec", e.g., "recXXXXXXXXXXXXXX") |
  | `fields` | json | Yes | An object containing the field names and their new values |
  | `typecast` | boolean | No | When true, Airtable automatically converts string values to the field type |

  #### Output [#output-5]

  | Parameter | Type | Description |
  | - | - | - |
  | `record` | json | Updated Airtable record |
  | ↳ `id` | string | Record ID |
  | ↳ `createdTime` | string | Record creation timestamp |
  | ↳ `fields` | json | Record field values |
  | `metadata` | json | Operation metadata |
  | ↳ `recordCount` | number | Number of records updated (always 1) |
  | ↳ `updatedFields` | array | List of field names that were updated |
</ReferenceDetails>

### Airtable Update Multiple Records [#airtable-update-multiple-records]

Update multiple existing records in an Airtable table

<ReferenceDetails>
  #### Input [#input-6]

  | Parameter | Type | Required | Description |
  | - | - | - | - |
  | `baseId` | string | Yes | Airtable base ID (starts with "app", e.g., "appXXXXXXXXXXXXXX") |
  | `tableId` | string | Yes | Table ID (starts with "tbl") or table name |
  | `records` | json | Yes | Array of records to update, each with an `id` and a `fields` object |
  | `typecast` | boolean | No | When true, Airtable automatically converts string values to the field type |

  #### Output [#output-6]

  | Parameter | Type | Description |
  | - | - | - |
  | `records` | array | Array of updated Airtable records |
  | ↳ `id` | string | Record ID |
  | ↳ `createdTime` | string | Record creation timestamp |
  | ↳ `fields` | json | Record field values |
  | `metadata` | json | Operation metadata |
  | ↳ `recordCount` | number | Number of records updated |
  | ↳ `updatedRecordIds` | array | List of updated record IDs |
</ReferenceDetails>

### Airtable Upsert Records [#airtable-upsert-records]

Update existing records or create new ones in an Airtable table, matching on the specified merge fields

<ReferenceDetails>
  #### Input [#input-7]

  | Parameter | Type | Required | Description |
  | - | - | - | - |
  | `baseId` | string | Yes | Airtable base ID (starts with "app", e.g., "appXXXXXXXXXXXXXX") |
  | `tableId` | string | Yes | Table ID (starts with "tbl") or table name |
  | `records` | json | Yes | Array of records to upsert, each with a `fields` object |
  | `fieldsToMergeOn` | json | Yes | Array of field names used to match existing records (max 3). A record is updated when all merge fields match, otherwise it is created. Example: \["Name"] |
  | `typecast` | boolean | No | When true, Airtable automatically converts string values to the field type |

  #### Output [#output-7]

  | Parameter | Type | Description |
  | - | - | - |
  | `records` | array | Array of upserted Airtable records |
  | ↳ `id` | string | Record ID |
  | ↳ `createdTime` | string | Record creation timestamp |
  | ↳ `fields` | json | Record field values |
  | `createdRecords` | array | IDs of records that were created |
  | `updatedRecords` | array | IDs of records that were updated |
  | `metadata` | json | Operation metadata |
  | ↳ `recordCount` | number | Total number of records returned |
  | ↳ `createdCount` | number | Number of records created |
  | ↳ `updatedCount` | number | Number of records updated |
</ReferenceDetails>

### Airtable Delete Records [#airtable-delete-records]

Delete one or more records from an Airtable table by ID

<ReferenceDetails>
  #### Input [#input-8]

  | Parameter | Type | Required | Description |
  | - | - | - | - |
  | `baseId` | string | Yes | Airtable base ID (starts with "app", e.g., "appXXXXXXXXXXXXXX") |
  | `tableId` | string | Yes | Table ID (starts with "tbl") or table name |
  | `recordIds` | json | Yes | Array of record IDs to delete (each starts with "rec", e.g., \["recXXXXXXXXXXXXXX"]). Pass a single-element array to delete one record. |

  #### Output [#output-8]

  | Parameter | Type | Description |
  | - | - | - |
  | `records` | array | Array of deleted Airtable records |
  | ↳ `id` | string | Record ID |
  | ↳ `deleted` | boolean | Whether the record was deleted |
  | `metadata` | json | Operation metadata |
  | ↳ `recordCount` | number | Number of records deleted |
  | ↳ `deletedRecordIds` | array | List of deleted record IDs |
</ReferenceDetails>

### Airtable Get Base Schema [#airtable-get-base-schema]

Get the schema of all tables, fields, and views in an Airtable base

<ReferenceDetails>
  #### Input [#input-9]

  | Parameter | Type | Required | Description |
  | - | - | - | - |
  | `baseId` | string | Yes | Airtable base ID (starts with "app", e.g., "appXXXXXXXXXXXXXX") |

  #### Output [#output-9]

  | Parameter | Type | Description |
  | - | - | - |
  | `tables` | json | Array of table schemas with fields and views |
  | `metadata` | json | Operation metadata including total tables count |
</ReferenceDetails>

## Triggers [#triggers]

A trigger starts a workflow when a supported event occurs in this service.

### Airtable Webhook [#airtable-webhook]

Trigger workflow from Airtable record changes like create, update, and delete events (requires Airtable credentials)

<ReferenceDetails label="Configuration and outputs">
  #### Configuration [#configuration]

  | Parameter | Type | Required | Description |
  | - | - | - | - |
  | `triggerCredentials` | string | Yes | This trigger requires airtable credentials to access your account. |
  | `baseId` | string | Yes | The ID of the Airtable Base this webhook will monitor. |
  | `tableId` | string | Yes | The ID of the table within the Base that the webhook will monitor. |
  | `includeCellValues` | boolean | No | Enable to receive the complete record data in the payload, not just changes. |

  #### Output [#output-10]

  | Parameter | Type | Description |
  | - | - | - |
  | `payloads` | array | The payloads of the Airtable changes |
  | ↳ `timestamp` | string | Timestamp of the change |
  | ↳ `baseTransactionNumber` | number | Transaction number |
  | `latestPayload` | object | The most recent payload from Airtable |
  | ↳ `timestamp` | string | ISO 8601 timestamp of the change |
  | ↳ `baseTransactionNumber` | number | Transaction number |
  | ↳ `payloadFormat` | string | Payload format version (e.g., v0) |
  | ↳ `actionMetadata` | object | Metadata about who made the change |
  | ↳ `source` | string | Source of the change (e.g., client, publicApi) |
  | ↳ `sourceMetadata` | object | Source metadata including user info |
  | ↳ `user` | object | User who made the change |
  | ↳ `id` | string | User ID |
  | ↳ `email` | string | User email |
  | ↳ `name` | string | User name |
  | ↳ `permissionLevel` | string | User permission level |
  | ↳ `changedTablesById` | object | Tables that were changed (keyed by table ID) |
  | ↳ `changedRecordsById` | object | Changed records keyed by record ID |
  | ↳ `current` | object | Current state of the record |
  | ↳ `cellValuesByFieldId` | object | Cell values keyed by field ID |
  | ↳ `createdRecordsById` | object | Created records by ID |
  | ↳ `destroyedRecordIds` | array | Array of destroyed record IDs |
  | `airtableChanges` | array | Consolidated record creations and updates. Deleted record IDs remain in raw payloads. |
  | ↳ `tableId` | string | Table ID |
  | ↳ `recordId` | string | Record ID |
  | ↳ `changeType` | string | Type of consolidated change: created or updated |
  | ↳ `cellValuesByFieldId` | object | Cell values by field ID |
</ReferenceDetails>
