Skip to main system content
TecSynth
← Blog
AI Automations7 min read

n8n Airtable to Notion Sync: The Full Tutorial (+ Free Template)

Sync new Airtable records into Notion automatically with n8n. Step-by-step setup, property mapping that actually works, a copy-paste workflow JSON, and fixes for the common errors.

n8n Airtable NotionAirtable to Notion Syncn8n TutorialNotion AutomationAirtable AutomationWorkflow Template

Quick answer: Add an Airtable trigger node in n8n that polls your base for new records, then connect a Notion node that creates a page in your target database and maps each Airtable field to a Notion property. Setup takes about 15 minutes, and the workflow JSON below imports directly.

This tutorial covers the full setup, the property mapping step where most people get stuck, and how to extend the sync to handle updates.

What You Need Before Starting

ComponentPurposeCost
n8n instanceRuns the syncFree self-hosted, or n8n Cloud from about $20/mo
Airtable account with a personal access tokenThe source baseFree plan works
Notion account with an internal integrationThe target databaseFree plan works
A Notion database with matching propertiesWhere records landFree

Create the Notion integration at notion.so/my-integrations, then share the target database with it. This step is mandatory: an integration that has not been added to the database sees nothing, and it is the number one setup mistake.

Step 1: Add the Airtable Trigger

Create a new workflow and add the Airtable Trigger node. Authenticate with your personal access token, then select the base and table to watch.

Set the trigger to fire on new records and choose the polling interval. Every minute is right for active tables.

Step 2: Add the Notion Node and Map Properties

Add a Notion node, set the resource to Database Page and the operation to Create. Select your target database.

Now map the fields. For each Notion property, switch the value to expression mode and reference the Airtable field by its exact column name:

Name property: {{ $json.fields.Name }}
Email property: {{ $json.fields.Email }}
Status property: {{ $json.fields.Status }}

Two rules save an hour of debugging. Airtable nests everything under fields, so the path is always $json.fields.YourColumn. And Notion select properties reject values that do not already exist as options, so create the options in Notion first.

Step 3: Test and Activate

Click Execute Workflow, add a record in Airtable, and watch it appear as a page in your Notion database. When the mapping looks right, activate the workflow. The sync now runs unattended.

The Free Workflow Template

Import this JSON into a blank n8n canvas, then reconnect your own credentials and reselect your base, table, and database:

{
  "name": "Airtable to Notion Sync",
  "nodes": [
    {
      "parameters": {
        "pollTimes": { "item": [{ "mode": "everyMinute" }] },
        "baseId": { "__rl": true, "mode": "list", "value": "REPLACE_WITH_BASE_ID" },
        "tableId": { "__rl": true, "mode": "list", "value": "REPLACE_WITH_TABLE_ID" },
        "triggerField": "Created"
      },
      "id": "airtable-trigger-1",
      "name": "Airtable Trigger",
      "type": "n8n-nodes-base.airtableTrigger",
      "typeVersion": 1,
      "position": [260, 300]
    },
    {
      "parameters": {
        "resource": "databasePage",
        "operation": "create",
        "databaseId": { "__rl": true, "mode": "list", "value": "REPLACE_WITH_DATABASE_ID" },
        "title": "={{ $json.fields.Name }}",
        "propertiesUi": {
          "propertyValues": [
            { "key": "Email|email", "emailValue": "={{ $json.fields.Email }}" },
            { "key": "Status|select", "selectValue": "={{ $json.fields.Status }}" }
          ]
        }
      },
      "id": "notion-1",
      "name": "Notion",
      "type": "n8n-nodes-base.notion",
      "typeVersion": 2.2,
      "position": [520, 300]
    }
  ],
  "connections": {
    "Airtable Trigger": {
      "main": [[{ "node": "Notion", "type": "main", "index": 0 }]]
    }
  },
  "active": false,
  "settings": { "executionOrder": "v1" }
}

How Do You Handle Updates to Existing Records?

Add a Last Modified Time field in Airtable and switch the trigger to watch it. Then, before the Notion create step, add a Notion search that looks up the page by a unique property such as the Airtable record ID. An IF node routes the result: page found goes to an update operation, page missing goes to create.

Store the Airtable record ID in a dedicated Notion property from day one. It is the reliable join key that makes updates, deduplication, and debugging possible.

What Should You Build Next?

The same trigger-map-create pattern drives most database mirroring: CRM to reporting base, form tool to project tracker, support tool to knowledge base. If this is your first n8n workflow, our Google Sheets to Slack tutorial is the simplest next rep, and the workflow audit helps you pick which process deserves automation next. Watching costs as your workflows multiply? See the EU pricing breakdown.

FAQ

Why are my Airtable fields arriving empty in Notion?

Field name mismatch is the usual cause. n8n expressions reference Airtable fields by their exact column name, including spaces and capitalization. Rename checks aside, confirm the record actually has a value: Airtable returns no key at all for empty cells, so map optional fields defensively.

Can this sync work in both directions?

Two-way sync is possible but is a much harder problem than it looks, because each side edits the same records and loops must be prevented. For most teams we recommend one direction of truth: Airtable as the source and Notion as the mirror, or the reverse. Build two-way sync only with a clear conflict rule.

Does the sync fire instantly when a record is added?

No. The Airtable trigger polls on an interval, with every minute as the tightest standard setting, so a new record appears in Notion within about a minute. For most database mirroring that delay is invisible. If you need true real-time, use an Airtable automation to call an n8n webhook instead.

How do I sync record updates, not just new records?

Airtable makes this easy: add a Last Modified Time field to your table and have the trigger watch it. In n8n, use the trigger's update event with that field selected. Pair it with a Notion search step that finds the existing page by a unique ID property, then update instead of create.