MyBotBoxMyBotBox

Airtable

Trigger workflows on Airtable record create / update / delete events.

The Airtable trigger fires when a record is created, updated, or deleted in a watched base. Airtable's webhook delivers a ping notification that the platform follows by calling Airtable's GET /v0/bases/<baseId>/webhooks/<webhookId>/payloads to fetch the actual changes.

How to configure

  1. Connect an Airtable credential to this workflow first — Airtable webhooks require API access to read changed cells. Visit airtable.com/create/tokens and grant the data.records:read + webhook:manage scopes on the base you want to watch.
  2. Save the trigger. MyBotBox calls Airtable's Create Webhook API behind the scenes and registers the URL above as the notificationUrl. The base + table you select on this trigger become the specification.options.filters.
  3. Airtable does not deliver the changed-cell payload in the POST body — it sends a ping notification, then the platform calls GET /v0/bases/<baseId>/webhooks/<webhookId>/payloads to fetch payloads[]. Downstream blocks reference <airtable1.latestPayload.actionMetadata.source>, <airtable1.airtableChanges>, etc.
  4. To verify end-to-end: add or edit a record in the watched table, then check this workflow's execution log within ~30 seconds. Re-deploy the workflow after any subBlocks change so Airtable picks up the new filter spec.

Authentication

Airtable webhooks use Airtable's own MAC signature on the inbound ping (X-Airtable-Content-MAC: <base64-mac>) which the platform validates against the per-webhook secret Airtable returned at create time. There is no shared signing secret on the MyBotBox side — auth is established by the OAuth credential you connect.

The dedup key is webhookId + baseTransactionNumber, so Airtable's at-least-once ping delivery yields exactly-once workflow runs.

Sample payload (after follow-up payloads fetch)

{
  "base": { "id": "appXXXXXXXXXXXXXX" },
  "webhook": { "id": "achXXXXXXXXXXXXXX" },
  "timestamp": "2026-04-26T21:00:00.000Z",
  "payloads": [
    {
      "timestamp": "2026-04-26T21:00:00.000Z",
      "baseTransactionNumber": 42,
      "actionMetadata": {
        "source": "client",
        "sourceMetadata": { "user": { "id": "usrXXXXXXXXXXXXXX", "email": "user@example.com" } }
      },
      "payloadFormat": "v0",
      "changedTablesById": {
        "tblXXXXXXXXXXXXXX": {
          "changedRecordsById": {
            "recXXXXXXXXXXXXXX": {
              "current": { "cellValuesByFieldId": { "fldNameId": "Updated value" } },
              "previous": { "cellValuesByFieldId": { "fldNameId": "Old value" } }
            }
          }
        }
      }
    }
  ]
}

Verify with the bundled scripts

bun apps/sat/tests/staging/triggers/airtable/verify.ts \
  https://mybotbox.com/api/webhooks/trigger/<path>
python3 apps/sat/tests/staging/triggers/airtable/verify.py \
  https://mybotbox.com/api/webhooks/trigger/<path>

The script POSTs an Airtable-shaped ping payload (no signing secret, since Airtable's auth model is one-sided). Production verification flows through the OAuth credential and Airtable's own retry semantics. Source: apps/sat/tests/staging/triggers/airtable/.

Troubleshooting

  • No fire after editing a record — confirm the OAuth credential still works (Airtable tokens expire). Inspect the trigger row's consecutive_failures/last_error columns; if they show 401, re-authorize the credential.
  • Trigger fires but payload is empty — Airtable's payloads fetch returns [] after a long latency. Re-edit the same record; the platform automatically advances the cursor so old changes are not re-delivered.
  • Renaming a watched table breaks the trigger — Airtable webhook filters are keyed by table ID, but on rename the API call to fetch payloads can fail. Re-save the trigger to re-register with the new table identifier.
  • Duplicates — the trigger dedupes on (webhookId, baseTransactionNumber) via webhook_event_dedup. If you see dupes, confirm migration 0109 has been applied.