DEV Community

Pirate Prentice
Pirate Prentice

Posted on

n8n Airtable Node: Read, Create, Update, and Delete Records (Free JSON)

n8n Airtable Node: Read, Create, Update, and Delete Records (Free JSON)

Airtable is one of the most popular no-code databases — part spreadsheet, part database, fully visual. If your team lives in Airtable, the n8n Airtable node lets you automate every record operation without writing a line of Airtable scripting.

This guide covers setup, every operation with examples, common gotchas, and a free workflow JSON you can import directly.


Prerequisites

  • n8n instance (cloud or self-hosted)
  • An Airtable account with at least one base
  • An Airtable personal access token (API key is deprecated as of Feb 2024)

Step 1: Create an Airtable Personal Access Token

  1. Go to airtable.com/accountDeveloper HubPersonal access tokens
  2. Click + Create new token
  3. Name it (e.g., n8n-integration)
  4. Add scopes: at minimum data.records:read, data.records:write, schema.bases:read
  5. Under Access, select the specific bases you want n8n to reach (or all bases)
  6. Copy the token — it only shows once

Why scopes matter: Airtable's new token system is scope-based. If you forget data.records:write and try to create a record, you'll get a 403 with no helpful error message. Match your scopes to the operations you plan to use.


Step 2: Add the Credential in n8n

  1. In n8n, go to CredentialsNew → search Airtable
  2. Select Airtable Personal Access Token
  3. Paste your token
  4. Click Save — n8n verifies the connection immediately

Step 3: Add the Airtable Node to Your Workflow

  1. Click + in the workflow canvas
  2. Search for Airtable
  3. Select the operation you need (see below)

All Airtable Node Operations

Search Records

Searches your table using a filter formula and returns matching records.

Key settings:

  • Base: select your Airtable base
  • Table: select the table
  • Filter By Formula: Airtable formula syntax, e.g., {Status} = "Active" or IS_BEFORE({Due Date}, TODAY())
  • Return All: toggle on to get every matching record; otherwise returns up to 100

Output: Array of record objects, each with id and fields.

// Example output item
{
  "id": "recABC123",
  "fields": {
    "Name": "Acme Corp",
    "Status": "Active",
    "Revenue": 50000
  }
}
Enter fullscreen mode Exit fullscreen mode

Common use case: Pull all "Active" leads every morning and send a Slack summary.


List Records

Returns all records in a table (with optional sort and filter).

Difference from Search: List is for bulk retrieval; Search is when you have a specific formula condition. In practice they overlap — use whichever feels clearer for your use case.

Key settings:

  • Sort: add sort fields and direction (ascending/descending)
  • Fields: list only the fields you need (reduces payload size)
  • View: restrict to a specific Airtable view's records

Get Record

Fetches a single record by its record ID.

Key settings:

  • Record ID: the recXXXXXXXXXX string (usually passed from a prior Search/List node)

Use case: After a webhook fires with a record ID, fetch the full record details before processing.


Create Record

Adds one new record to a table.

Key settings:

  • Fields: map n8n expressions to Airtable field names
Name          → {{ $json.name }}
Email         → {{ $json.email }}
Source        → "n8n webhook"
Created Date  → {{ $now.toISO() }}
Enter fullscreen mode Exit fullscreen mode

Field name must match exactly. Airtable field names are case-sensitive. "email" and "Email" are different fields. If a field doesn't exist in the table, the node silently ignores it — no error, just missing data.


Update Record

Updates fields on an existing record.

Key settings:

  • Record ID: the ID of the record to update (from a prior node)
  • Fields: only the fields you want to change (unspecified fields are left unchanged)

Common pattern:

[Trigger] → [Search Records: find by email] → [Update Record: set Status = "Replied"]
Enter fullscreen mode Exit fullscreen mode

Upsert Record (Create or Update)

Checks if a record matching your field value exists; updates it if found, creates it if not.

Key settings:

  • Fields to Match On: the field(s) used to find an existing record (e.g., "Email")
  • Fields: the values to set/update

This is the most powerful operation for sync workflows — it keeps Airtable in sync with an external source without creating duplicates.


Delete Record

Permanently deletes a record by ID. Irreversible.

Key settings:

  • Record ID: pass from a Search/List node

Operation Quick Reference

Operation When to use
Search Records Filter by formula — get records matching a condition
List Records Get all records, optionally sorted/filtered by view
Get Record Fetch one record by known ID
Create Record Add a new row
Update Record Change fields on an existing row (ID required)
Upsert Record Sync external data — create if new, update if exists
Delete Record Remove a row permanently

Common Gotchas

1. Old API key vs. Personal Access Token

Airtable deprecated API keys in February 2024. If you see a 401 error, you're using the old credential type. Delete the old credential in n8n and create a new Airtable Personal Access Token credential.

2. Formula syntax in Filter By Formula

Airtable formulas use their own syntax. Common mistakes:

  • Field names with spaces need curly braces: {First Name} not First Name
  • String values need quotes: {Status} = "Active" not {Status} = Active
  • Dates: use IS_BEFORE(), IS_AFTER(), TODAY() — not JavaScript date methods

3. Rate limits

Airtable's API rate limit is 5 requests per second per base. If you're looping over hundreds of records and creating/updating each one individually, you'll hit 429 errors. Solutions:

  • Add a Wait node (1 second) between batches
  • Use a Split in Batches node with a small batch size
  • Use Upsert to combine create + update into one call where possible

4. Field type mismatches

Airtable is strict about field types. You cannot write a string to a Number field or an array to a Single Line Text field. If your data comes from an external source, validate/convert types in a Code or Set node before the Airtable node.

5. Linked Record fields

Linked Record fields in Airtable store arrays of record IDs, not display values. To write to a linked field:

{ "Project": ["recXXXX", "recYYYY"] }
Enter fullscreen mode Exit fullscreen mode

To read the display value of a linked record, you need a second Airtable Get Record call on the linked table.


Free Workflow: Webhook → Airtable Lead Capture

This workflow receives a webhook (e.g., from a contact form) and upserts the lead into an Airtable CRM base — no duplicates, no manual data entry.

{
  "name": "Webhook → Airtable Lead Capture",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "new-lead",
        "responseMode": "responseNode"
      },
      "id": "a1b2c3d4-0001-0001-0001-000000000001",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [250, 300]
    },
    {
      "parameters": {
        "operation": "upsert",
        "base": { "__rl": true, "value": "YOUR_BASE_ID", "mode": "id" },
        "table": { "__rl": true, "value": "YOUR_TABLE_ID", "mode": "id" },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Email": "={{ $json.body.email }}",
            "Name": "={{ $json.body.name }}",
            "Company": "={{ $json.body.company }}",
            "Source": "n8n webhook",
            "Last Seen": "={{ $now.toISO() }}"
          }
        },
        "matchingColumns": ["Email"]
      },
      "id": "a1b2c3d4-0002-0002-0002-000000000002",
      "name": "Airtable",
      "type": "n8n-nodes-base.airtable",
      "typeVersion": 2,
      "position": [450, 300]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={ \"ok\": true }"
      },
      "id": "a1b2c3d4-0003-0003-0003-000000000003",
      "name": "Respond to Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [650, 300]
    }
  ],
  "connections": {
    "Webhook": { "main": [[{ "node": "Airtable", "type": "main", "index": 0 }]] },
    "Airtable": { "main": [[{ "node": "Respond to Webhook", "type": "main", "index": 0 }]] }
  }
}
Enter fullscreen mode Exit fullscreen mode

To use this:

  1. Replace YOUR_BASE_ID and YOUR_TABLE_ID with your actual IDs (find them in your Airtable URL: airtable.com/YOUR_BASE_ID/YOUR_TABLE_ID)
  2. Add your Airtable credential to the node
  3. Adjust field names to match your table

What's in the n8n Workflow Starter Pack?

The free JSON above handles the basics. The n8n Workflow Starter Pack ($29) includes:

  • 15 production-ready workflows (Airtable, Notion, Slack, Gmail, Stripe, OpenAI, and more)
  • Complete setup instructions for each
  • Error handling and retry logic built in
  • Airtable-specific workflows: lead capture, CRM sync, inventory alerts, form-to-base

One purchase, instant download, no subscription.


Summary

The n8n Airtable node covers the full CRUD surface of your bases. The main things to get right:

  1. Use a Personal Access Token (not the deprecated API key)
  2. Set the right scopes on the token
  3. Match field names exactly (case-sensitive)
  4. Use Upsert for sync workflows to avoid duplicates
  5. Respect the 5 req/sec rate limit with Wait or batch nodes

If you're building automations that touch Airtable regularly, this node will become one of your most-used.


What Airtable automation are you trying to build? Drop it in the comments — happy to help with the formula or field mapping.

Top comments (1)

Collapse
 
pirateprentice profile image
Pirate Prentice

Curious what you all are using Airtable for in your n8n workflows — CRM, project tracking, inventory? The Upsert operation is what I reach for most when syncing from an external source. What's your most-used Airtable → n8n combo?