Reference · Tools
Airtable
Read, create, update, upsert, delete, and search records in Airtable bases. Download attachment fields as binary data. List bases and retrieve base schemas.
The Airtable node connects your workflows to Airtable bases with full CRUD support — create, read, update, delete, search, and upsert records without writing API calls yourself. You can also download attachment field content as binary data, making it straightforward to pull images or files from Airtable into downstream processing steps. A typical use case is syncing form submissions into an Airtable base and routing the uploaded file attachments to cloud storage.
- Node type
- Action (binary)
- Parameters
- 25
- Outputs
- Output, Error
- Credentials
- Airtable API
Airtable
Read, create, update, delete, and search Airtable records with attachment download
Overview
The Airtable tool provides full CRUD operations for Airtable records via the Airtable REST API v0. Supports two resources: (1) Record — create, delete, get, search (list/filter), update, and upsert. Record get and search operations can optionally download attachment fields as binary data with naming pattern {fieldName}_{index}. (2) Base — list all accessible bases with permission filtering, and retrieve the full schema (tables, fields, views) of a base. Uses Bearer token authentication. Supports pagination for search (offset-based, 100 records/page), auto-batching for update/upsert (max 10 records/PATCH), and upsert fallback logic for 422 errors and multi-match scenarios.
Category: Data & Storage
Tool Name: airtable
Version: 1
Appearance: Icon: si-airtable | Color: #18BFFF
Node Type
Action (Binary) — handles file/binary data operations
Input / Output
| Direction | Port(s) |
|---|---|
| Input | Input |
| Output | Output, Error |
Credentials
This tool requires Airtable API credentials. See the Credentials Guide for setup instructions.
Resources
| Resource | Value |
|---|---|
| Base | base |
| Record | record |
Operations
Operations for the record resource:
| Operation | Value | Description |
|---|---|---|
| Create | create | Create a new record in a table |
| Delete | delete | Delete a record by ID |
| Get | get | Retrieve a single record by ID |
| Search | search | Search for records or list all |
| Update | update | Update an existing record |
| Upsert | upsert | Create or update a record |
Operations for the base resource:
| Operation | Value | Description |
|---|---|---|
| Get Many | getMany | List all accessible bases |
| Get Schema | getSchema | Get the schema of a base |
Parameters
Record: Create
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Base ID | string | Yes | — | The Airtable Base ID. Find it in the URL: https://airtable.com/{baseId}/… |
| Table ID | string | Yes | — | The Table ID or name (URI-encoded if name contains special characters). |
| Fields (JSON) | json | Yes | {} | Key-value pairs of column name to value. Example: {“Name”: “John”, “Email”: “john@example.com”}. Set to “autoMap” to auto-map all input item JSON fields. |
| Typecast | boolean | No | false | Whether the Airtable API should attempt mapping of string values for linked records and select options. |
| Ignore Fields | string | No | — | Comma-separated list of fields to ignore when auto-mapping input data. |
Record: Delete
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Base ID | string | Yes | — | The Airtable Base ID. Find it in the URL: https://airtable.com/{baseId}/… |
| Table ID | string | Yes | — | The Table ID or name (URI-encoded if name contains special characters). |
| Record ID | string | Yes | — | The ID of the record to delete. |
Record: Get
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Base ID | string | Yes | — | The Airtable Base ID. Find it in the URL: https://airtable.com/{baseId}/… |
| Table ID | string | Yes | — | The Table ID or name (URI-encoded if name contains special characters). |
| Record ID | string | Yes | — | The ID of the record to retrieve. |
| Download Attachments | string | No | — | Comma-separated names of attachment-type fields to download as binary data. Binary properties are named {fieldName}_{index}. Leave empty to skip attachment download. |
Record: Search
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Base ID | string | Yes | — | The Airtable Base ID. Find it in the URL: https://airtable.com/{baseId}/… |
| Table ID | string | Yes | — | The Table ID or name (URI-encoded if name contains special characters). |
| Filter By Formula | string | No | — | Airtable formula to filter records. If empty, all records are returned. See https://support.airtable.com/docs/formula-field-reference |
| Return All | boolean | No | true | Whether to return all results or only up to a given limit. |
| Limit | number | No | 100 | Max number of records to return (max 100). (shown when Return All is false) |
| Download Attachments | string | No | — | Comma-separated names of attachment-type fields to download as binary data. Binary properties are named {fieldName}_{index}. Leave empty to skip attachment download. |
| Output Fields | string | No | — | Comma-separated list of field names to include in the output. Leave empty to return all fields. |
| View | string | No | — | View ID or name to filter by. Only records visible in this view will be returned. |
| Sort | json | No | [] | Sort rules as JSON array: [{“field”: “Name”, “direction”: “asc”}, {“field”: “Date”, “direction”: “desc”}]. direction can be “asc” or “desc”. |
Record: Update
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Base ID | string | Yes | — | The Airtable Base ID. Find it in the URL: https://airtable.com/{baseId}/… |
| Table ID | string | Yes | — | The Table ID or name (URI-encoded if name contains special characters). |
| Fields (JSON) | json | Yes | {} | Key-value pairs of column name to value to update. Include matching column values. Set to “autoMap” to auto-map all input item JSON fields. |
| Matching Columns | string | Yes | id | Comma-separated list of columns to match on. Use “id” to match by Airtable record ID. For upsert, these columns identify whether to create or update. |
| Typecast | boolean | No | false | Whether the Airtable API should attempt mapping of string values for linked records and select options. |
| Ignore Fields | string | No | — | Comma-separated list of fields to ignore when auto-mapping input data. |
| Update All Matches | boolean | No | false | Whether to update all records matching the matching columns. If false, only the first match is updated. |
Record: Upsert
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Base ID | string | Yes | — | The Airtable Base ID. Find it in the URL: https://airtable.com/{baseId}/… |
| Table ID | string | Yes | — | The Table ID or name (URI-encoded if name contains special characters). |
| Fields (JSON) | json | Yes | {} | Key-value pairs of column name to value to update. Include matching column values. Set to “autoMap” to auto-map all input item JSON fields. |
| Matching Columns | string | Yes | id | Comma-separated list of columns to match on. Use “id” to match by Airtable record ID. For upsert, these columns identify whether to create or update. |
| Typecast | boolean | No | false | Whether the Airtable API should attempt mapping of string values for linked records and select options. |
| Ignore Fields | string | No | — | Comma-separated list of fields to ignore when auto-mapping input data. |
| Update All Matches | boolean | No | false | Whether to update all records matching the matching columns. If false, only the first match is updated. |
Base: Get Many
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Return All | boolean | No | true | Whether to return all bases or only up to a given limit. |
| Limit | number | No | 100 | Max number of bases to return. (shown when Return All is false) |
| Permission Level | multiOptions | No | [] | Filter returned bases by permission level. |
Options: comment, create, edit, none, read |
Base: Get Schema
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Base ID | string | Yes | — | The Airtable Base ID to retrieve the schema from. |
All Operations
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Max Concurrency | number | No | 5 | Maximum number of items to process concurrently. Airtable rate limits to 5 requests/second per base, so keep this low. |
Output Data
Results are merged onto the input item’s JSON, so the properties you started with remain available. Airtable’s fields object is flattened: every column becomes a top-level property of the item, alongside the record’s id and createdTime. Binary data on the input item is forwarded.
| Operation | Output |
|---|---|
create | One item per input item, carrying the created record — its id and every column. |
get | One item per input item, carrying the requested record. |
delete | One item per input item, carrying Airtable’s delete confirmation for that record ID. |
search | Fans out — one output item per matching record. |
update | One item per input item. A single match is flattened onto the item; when several records were updated they arrive as an array on updatedRecords. |
upsert | One item per input item. A single match is flattened onto the item; when several records were written they arrive as an array on upsertedRecords. |
getMany | Fans out — one output item per accessible base, carrying that base’s metadata including its permissionLevel. |
getSchema | Fans out — one output item per table in the base, carrying that table’s definition (fields and views). |
Operations that fan out emit a single item carrying _noResults: true when nothing matched, so the branch never goes silent. Check for it before treating the item as a record:
{
"_noResults": true
}
Attachments. With Download Attachments set on get or search, every attachment in the named fields is downloaded and attached to the output item as binary. Each binary property is named {fieldName}_{index} — the first file in a Documents field becomes Documents_0, the second Documents_1. The record’s JSON still carries Airtable’s own attachment metadata, so you can read the original file name from there and the bytes from the binary property.
Reference results downstream by expression, e.g. {{ $json.id }} or {{ $json.Email }}.
Usage Examples
- Search all records in an Airtable table and download attachment fields
- Create a new record in Airtable with typecast enabled
- Update an Airtable record matched by email column
- Upsert records to avoid duplicates using a unique column
- List all accessible Airtable bases
- Get the schema (tables and fields) of an Airtable base
Example Configuration
Create a record:
{
"type": "airtable",
"parameters": {
"resource": "record",
"operation": "create",
"baseId": "appXXXXXXXXXXXXXX",
"tableId": "tblYYYYYYYYYYYYYY",
"fields": {
"Name": "{{ $json.name }}",
"Email": "{{ $json.email }}",
"Age": 30
},
"typecast": true
}
}
Map every property of the incoming item to a column, skipping the ones Airtable should not see:
{
"type": "airtable",
"parameters": {
"resource": "record",
"operation": "create",
"baseId": "appXXXXXXXXXXXXXX",
"tableId": "tblYYYYYYYYYYYYYY",
"fields": "autoMap",
"ignoreFields": "internal_id,temp_field",
"typecast": true
}
}
Search with a formula, sorted, returning only the columns you need:
{
"type": "airtable",
"parameters": {
"resource": "record",
"operation": "search",
"baseId": "appXXXXXXXXXXXXXX",
"tableId": "tblYYYYYYYYYYYYYY",
"filterByFormula": "AND({Status} = 'Active', {Age} > 25)",
"returnAll": false,
"limit": 50,
"sort": [
{ "field": "Name", "direction": "asc" },
{ "field": "Created", "direction": "desc" }
],
"outputFields": "Name,Email,Status,Age"
}
}
Search a saved view and pull every attachment down as binary:
{
"type": "airtable",
"parameters": {
"resource": "record",
"operation": "search",
"baseId": "appXXXXXXXXXXXXXX",
"tableId": "tblYYYYYYYYYYYYYY",
"view": "viwActiveCustomers",
"filterByFormula": "AND({Last Contact} > DATEADD(TODAY(), -30, 'days'), {Priority} != '')",
"returnAll": true,
"sort": [{ "field": "Priority", "direction": "desc" }],
"downloadFields": "Contract,Invoice"
}
}
Get one record and download its attachments:
{
"type": "airtable",
"parameters": {
"resource": "record",
"operation": "get",
"baseId": "appXXXXXXXXXXXXXX",
"tableId": "tblYYYYYYYYYYYYYY",
"id": "{{ $json.recordId }}",
"downloadFields": "Profile Photo,Documents"
}
}
Update the record whose Email column matches:
{
"type": "airtable",
"parameters": {
"resource": "record",
"operation": "update",
"baseId": "appXXXXXXXXXXXXXX",
"tableId": "tblYYYYYYYYYYYYYY",
"fields": {
"Email": "{{ $json.email }}",
"Status": "Updated"
},
"matchingColumns": "Email",
"updateAllMatches": false,
"typecast": true
}
}
Upsert on a unique column so repeat runs do not create duplicates:
{
"type": "airtable",
"parameters": {
"resource": "record",
"operation": "upsert",
"baseId": "appXXXXXXXXXXXXXX",
"tableId": "tblYYYYYYYYYYYYYY",
"fields": {
"Email": "{{ $json.email }}",
"Name": "{{ $json.name }}",
"Status": "Active"
},
"matchingColumns": "Email",
"typecast": true
}
}
Delete a record by ID:
{
"type": "airtable",
"parameters": {
"resource": "record",
"operation": "delete",
"baseId": "appXXXXXXXXXXXXXX",
"tableId": "tblYYYYYYYYYYYYYY",
"id": "{{ $json.recordId }}"
}
}
List the bases you can edit or create in:
{
"type": "airtable",
"parameters": {
"resource": "base",
"operation": "getMany",
"returnAll": true,
"permissionLevel": ["edit", "create"]
}
}
Read a base’s schema, one item per table:
{
"type": "airtable",
"parameters": {
"resource": "base",
"operation": "getSchema",
"baseId": "appXXXXXXXXXXXXXX"
}
}
Error Handling
| Mode | Behavior |
|---|---|
| stop | Halts workflow on first error |
| continue | Skips failed items, passes successful ones through |
| errorPort | Routes failed items to Error output port |
Tips
Manage Airtable records (CRUD, search, upsert) and download attachment fields as binary data. Also list bases and retrieve base schemas.
Frequently asked questions
What authentication does this node use, and where do I get the credentials?
The node uses Airtable API credentials (credential type: airtableApi), authenticated via a Bearer token. You generate a personal access token from your Airtable account settings, then paste it into the BusyBot credential store. No OAuth flow is required.
What exactly happens when I use upsert, and how does it handle conflicts?
Upsert attempts to match existing records on a field you specify and update them if found, or create new ones if not. If the API returns a 422 error or finds multiple matching records, the node applies fallback logic rather than failing outright — so multi-match scenarios are handled gracefully rather than crashing your workflow.
How does the node handle large record sets — does it paginate automatically?
Yes. Search operations paginate automatically using Airtable's offset-based system, fetching up to 100 records per page until all results are retrieved. For update and upsert operations, records are auto-batched into groups of 10 per PATCH request, which is the API's maximum per call.
Can I download files attached to Airtable records, and how are they named?
Yes. The Get and Search (list/filter) record operations can optionally download attachment fields as binary data. Each downloaded file is named using the pattern {fieldName}_{index}, so if a record has two attachments in a field called 'Photos', they come out as Photos_0 and Photos_1. This binary output can then be passed directly to file storage or processing nodes.
Can I inspect what tables and fields exist in a base before building my workflow?
Yes. The Base resource includes a schema retrieval operation that returns the full structure of a base — tables, fields, and views — without touching any record data. There is also a list operation that shows all bases your API token can access, with permission filtering applied.
Build with the Airtable node
Drop it into a workflow, wire it to an agent, or call it on a schedule. You'll need Airtable API credentials first.
Open BusyBotLast updated . Spotted something wrong? Tell us.