New to Kestra?
Use blueprints to kickstart your first workflows.
Automate a Google Sheets to Airtable sync with Kestra. Poll a pitch submission sheet hourly and create Airtable records for editorial review.
Keep your editorial intake in sync without manual copy and paste. This blueprint watches a Google Sheet that captures article pitch submissions (title, author, and URL per row) and automatically creates a matching record in an Airtable table for review and assignment. It closes the gap between a lightweight submission form backed by Sheets and the structured Airtable base where your team triages, assigns, and tracks each pitch, so nothing slips through and no one has to babysit a spreadsheet.
io.kestra.plugin.googleworkspace.sheets.SheetModifiedTrigger, polls the spreadsheet on a fixed interval (every hour by default) and fires on CREATE_OR_UPDATE revisions. With includeDetails: true it computes a detailed diff and exposes the changed rows on trigger.modifications.log_sheet_changes task (io.kestra.plugin.core.log.Log) prints trigger.modifications as JSON so you can confirm the payload shape before mapping fields.create_airtable_record task (io.kestra.plugin.airtable.records.Create) writes a new row into the Editorial Pitches table, mapping Title, Author, and URL from the modified rows. It uses typecast: true so Airtable coerces values into the right column types, and runIf: "{{ trigger.count > 0 }}" so it only runs when there is an actual change to sync.runIf so empty polls do nothing.Google Sheets has no native scheduler that can react to a row change and call the Airtable API, and Airtable cannot reach back into your sheet. Kestra fills that gap with an event style polling trigger, declarative YAML you can version control, automatic retries on transient API failures, and full execution lineage so you can see exactly which pitch synced when. The stopAfter setting halts polling on FAILED or KILLED states to avoid repeated bad runs.
Editorial Pitches (or your own) with Title, Author, and URL columns.GOOGLE_SHEET_ID: the ID of the Google Sheet to watch.GCP_SERVICE_ACCOUNT_JSON: the service account JSON key used to read the sheet.AIRTABLE_API_KEY: an Airtable personal access token or API key.AIRTABLE_BASE_ID: the ID of the target Airtable base.sheetName and range to match where your pitch rows live (defaults: Pitches, A1:Z100).fields expressions match the JSON shape printed by log_sheet_changes, then adjust the trigger.modifications paths if your sheet diff differs.trigger.modifications[0] to batch multiple pitches per poll.interval for near real time intake, or add validation tasks to reject malformed rows.