List icon
OutputValues icon
If icon
SlackIncomingWebhook icon
Log icon
Schedule icon

Airtable Required Field Compliance Gate

List Airtable records missing a required field, alert Slack with the record IDs, and log the result for ops teams.

Categories
Business

A shared Airtable base drifts out of compliance one blank cell at a time: a record created without an owner, a status nobody set, a required approval field nobody filled in. Airtable has no native rule that pages anyone when a required field goes missing, it just sits blank until someone opens the view and notices. This blueprint reads what is actually blank right now, using Airtable's own formula filter, and reports it with the real record IDs attached.

This blueprint was created by Mohit Jeswani.

How it works

  1. list_incomplete_records (io.kestra.plugin.airtable.records.List) runs a filterByFormula of {<required_field_name>} = BLANK() against the table, so Airtable's own API does the blank check server-side instead of this flow paging through every record to check client-side. Read-only; nothing in Airtable is changed. allowFailure: true covers an API or auth error without failing the flow outright.
  2. evaluate (io.kestra.plugin.core.output.OutputValues) reads the matched count directly from the API response's own size field and collects the matched record IDs with a jq filter.
  3. route (io.kestra.plugin.core.flow.If):
    • compliant: logs that nothing is incomplete.
    • alert: posts the count and record IDs to Slack.
  4. summary logs the count and severity, closing the governance cycle.
  5. errors alerts Slack if the flow itself fails, for example an expired personal access token.

What you get

  • A count that is Airtable's own server-side filter result, not a client-side guess computed after paging through the whole table.
  • The exact record IDs in the Slack alert, so whoever responds can jump straight to the record instead of searching the view for it.
  • A read-only check with zero risk of overwriting a real record's data.

Who it's for

  • Ops and RevOps teams who run a process out of a shared Airtable base and need a required field enforced without manually scanning the view for blanks.
  • Teams evaluating the Airtable plugin who want a worked example of records.List used with filterByFormula for a governance check, distinct from this repo's existing Airtable blueprint, which only writes records via records.Create rather than auditing them.

Why orchestrate this with Kestra

Airtable's formula filter answers one query at a time; it does not keep a schedule, compare the result against a tolerance you declare, or notify a Slack channel when blanks pile up. Kestra keeps required_field_name and max_incomplete_count as flow inputs, turns the filtered query into a Slack page naming the actual record IDs, and keeps a full execution history of every run.

Prerequisites

  • An Airtable base with a table that has at least one record with required_field_name blank, to confirm the filter logic against.
  • An Airtable personal access token with read scope on that base.
  • A Slack incoming webhook URL.

This flow calls the Airtable API directly over HTTPS; there is no official local Airtable emulator, so list_incomplete_records cannot be exercised against a local Docker container.

Secrets

  • AIRTABLE_PERSONAL_ACCESS_TOKEN: the Airtable personal access token used by list_incomplete_records. In Kestra OSS, provide it as the base64-encoded environment variable SECRET_AIRTABLE_PERSONAL_ACCESS_TOKEN.
  • SLACK_WEBHOOK_URL: used by alert and the errors block. In Kestra OSS, provide it as the base64-encoded environment variable SECRET_SLACK_WEBHOOK_URL.

Inputs

Input Default Purpose
airtable_table_id <your-table-name> Table to audit
required_field_name Owner Field that must never be blank
max_incomplete_count 1 Blank-record count that triggers the Slack alert

Outputs

  • {{ outputs.list_incomplete_records.rows }}: every matched record (id, createdTime, fields).
  • {{ outputs.evaluate.values.incomplete_count }} / .incomplete_ids: how many records are incomplete and their IDs, semicolon-joined.
  • {{ outputs.evaluate.values.severity }}: OK, COMPLIANCE_BREACH, or CRITICAL.

Pitfalls

  • required_field_name must match the Airtable field's exact display name, including spacing and case; a mismatched name makes the formula reference a field that does not exist and the filter matches nothing rather than erroring.
  • BLANK() matches an empty text value or an unset field; a field explicitly set to the number 0 or the text "false" is not blank and will not match, which is correct behavior but can look surprising for a boolean-style field.
  • enableAutoPagination: true fetches every matching page; on a very large table with many blank records this can take several API calls, each subject to Airtable's own rate limits.

Quick start

  1. Add the AIRTABLE_PERSONAL_ACCESS_TOKEN and SLACK_WEBHOOK_URL secrets.
  2. Set airtable_base_id, airtable_table_id, and required_field_name to a real table and field.
  3. Run the flow manually and confirm summary logs a count.
  4. Blank out a known record's required field (or use one already blank) to confirm alert fires with its record ID.
  5. Enable the daily trigger once the inputs reflect your real base and compliance policy.

How to extend

  • Loop over several required_field_name values with io.kestra.plugin.core.flow.Loop to enforce more than one required field in a single scheduled run.
  • Chain io.kestra.plugin.airtable.records.Update on each incomplete record to set a "Needs Review" status field, gated behind an explicit confirm_flag input so tagging never runs by accident.
  • Group incomplete_ids by a "Team" or "Owner" field already present on related records to route each team's incomplete records to its own Slack channel.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.