← /how-to/

How to bulk edit Airtable records with AI

Airtable has no find and replace and no merge for select options. The fix: AI cleans your base as local files, and you approve every record as a diff. Try it now free → or book a demo with Curtis

Open the option list on your Status field and count. Three years into the shared base, it reads "Blog", "blog", "Blog post", and "BLOG draft", four colors for one kind of work, each variant backed by real rows, because 12,000 records accumulated faster than anyone agreed on names. Every grouped view now splits the same work four ways, and every chart undercounts. Airtable will rename an option cleanly, the change propagates to every record. Merging two options is the part with no button: reassign the rows yourself, then delete the orphan. And there is no find and replace anywhere in the product. The official help article on the subject hands you a SUBSTITUTE() formula and tells you to paste its output back over your own data.

The mess never stays in one column either. Titles that no longer name the thing, notes that ramble, linked records pointing at the duplicate company instead of the real one. Call it 90% mechanical, a mapping any script could apply, and 10% judgment: "BLOG draft" might belong under Blog or under Draft, and only reading the record settles it. The shape that handles both halves: pull the base into local files, let your AI agent build the variant inventory and apply the mapping with judgment, then review every changed record as a word-level diff before anything writes back to the base your whole team works in.

Your options

Hand edits in the grid

Filter a view down to one bad variant, type the canonical value into the top cell, copy it, select the column below it, paste. For one variant of one field, this is the fastest tool on this page. The limits arrive fast too. The grid cannot select non-contiguous rows, so the job becomes one filter-and-paste pass per variant, per field, and four variants across six fields is two dozen passes. Paste also applies one uniform value, so anything that needs per-row judgment, the retitles, the rambling notes, the ambiguous "BLOG draft" rows, stays one record at a time. Those rows do not fit any afternoon.

The extension shelf

Extensions left the free plan in 2023, so this shelf is paid plans only. Airtable's own find and replace lives here, as an example script for the Scripting extension: one table, one field, exact string per pass, with a before-and-after preview and a confirm prompt before it saves in batches of 50. The preview is the right instinct. Batch Update covers a narrow action list across a view: add or remove select options, sort multi-select values, nudge numbers and dates. Dedupe finds fuzzy duplicates, then merging is one duplicate set at a time, by hand. None of them reads a record and decides what it meant.

Formula gymnastics

The officially documented route. Add a helper field, nest one SUBSTITUTE() per variant, wait for it to compute, copy the column, paste it back over the original field, delete the helper. It does exactly what it says: exact strings, one field per pass, scaffolding columns sitting in a live base while you work. The paste back is the unprotected moment, because whatever lands in that column is live. And the formula has no opinion about "BLOG draft". A rule that maps it to "Blog" is wrong on every row that meant Draft, with perfect consistency.

Automations and scripting

The most capable route inside Airtable. The ceilings are specific: an automation's Find Records step returns at most 1,000 records per run, the Update Record action writes one record per action, and a script step stops dead at 30 seconds. The Scripting extension, run by hand in the browser, has no time limit and updates 50 records per call at up to 15 calls a second, so a well-batched script can work the whole table. What you give up: someone writes and debugs that script, it applies only the rules you encoded, and it writes straight to the live base. Undo is revision history, one record at a time, and a snapshot restores as a new base, not in place.

Scratch

Scratch moves the job onto files. The base comes down as a folder, one file per record, and the agent you already use gets full read and write on the editable fields: long-text and rich-text, titles, selects, dates, currency, numbers, attachment captions, linked-record references. Formulas, rollups, lookups, and autonumber fields are locked at the connector, so the cleanup has no write path to the computations the base runs on. Every change comes back as a word-level diff next to the original, validators check the option sets, and only approved records publish. The trade is stated plainly: the review is real reading, your reading, on purpose.

Option Whole base in one pass Judgment on messy rows Preview before live Undo after the write
Grid hand edits No, one filter-and-paste per variant Yours, row by row No, the grid is live Revision history, per record
Extensions One table, one field per pass No, exact match The script's before-and-after No
Formula helper column One field per pass No, exact match The helper column, if you read it No
Automations and scripting Yes, batched Only rules you coded Only if you build it No
Scratch Yes Yes, your agent Every change, as a word-level diff Per record, even after publish

How the loop works on your base

  1. Scratch pulls your base into files. A table or the whole base lands in a folder on your laptop, one file per record, every field laid out. The selects, titles, notes, dates, numbers, captions, and linked-record references sit there editable. The formula, rollup, lookup, and autonumber fields sit beside them, locked. Nothing on the live base has changed.
  2. Your AI builds the inventory, then cleans the records. Point Claude, Codex, Cursor, or Copilot at the folder and give it the brief. Inventory every value in the Status field, propose a canonical set, apply the mapping where it is unambiguous, and flag every row you cannot place. Wired to the API through an MCP server, an agent reads a base 100 records per page, capped at 5 requests a second, every page another round trip. On files, one grep counts every Status variant across all 12,000 rows in about a second. The agent scripts the mechanical 90% and reads the flagged rows itself, deciding from the record whether "BLOG draft" was ever a blog. It holds no API token, so it cannot touch the live base even if it tries.
  3. You review every diff and publish. Scratch lays each changed field next to the original, word by word, record by record. Validators run first if you set them, and the option set is the obvious one: a select value that does not exist on the live field gets flagged before you read a word. Approve what ships, and Scratch writes only those records back through the Airtable API, at the API's own pace, one approved record at a time. The agent did 99% of the work on the files. The last 1%, deciding what the base actually says, stays with you. It stays reversible too: reject a published record and the original values go back.

Here is the same loop running on a live base:

Claude

What people clean up

Questions people ask

Does Airtable have a find and replace?

No. The official support article on finding and replacing text documents a formula workaround: SUBSTITUTE() in a helper field, then paste the output back over your own column. The closest thing to a tool is an example script for the Scripting extension, one table and one field per pass, exact match only, on paid plans. Neither has an opinion about a row that does not fit the pattern.

Can I merge "Blog" and "Blog post" into one select option?

No, there is no merge button. Renaming one option is safe, since the change propagates to every record automatically. Merging two options means reassigning every affected record to the option you are keeping, then deleting the one left empty. The reassignment is the bulk edit, and it is the part this loop does with a diff on every record. Deleting the empty option afterward is one click in field settings.

Will the cleanup break my formulas, rollups, or automations?

No. Computed fields, meaning formulas, rollups, lookups, and autonumber, are read-only across Airtable's UI, automations, and API, and Scratch locks them at the connector besides, so the cleanup has no write path to them. What it does change is their inputs: fix 300 Status values and every rollup counting Status updates, which is the point, and the diff shows you each input change first. One honest note: a published record is an ordinary record update, so an automation watching that field fires the way it would for any edit.

Can the AI invent a select value my views do not expect?

It can. In the files, nothing stops it from writing "Blog posts" with an s. What stops it from shipping is the loop: validators check edited values against the option set and flag inventions before review, and every select change sits in the diff before anything writes back. An invented value ends on your screen, not in your views.

Can I see every change before it writes to the live base?

Yes. That is the design. Every changed field shows next to its original, word by word, record by record, and nothing reaches the base until you approve it. The agent works on local files and holds no API token.

Can I undo a change after it writes back?

Yes. Per record, from Scratch: the original stays next to the published change, and rejecting it puts the old values back. Airtable's own routes are coarser. Revision history restores one record at a time by hand, and a snapshot restores as a separate new base, not in place.

Is Airtable's built-in AI enough for this?

Partly. AI fields generate values per cell and can run across a view, metered by credits, and the Omni assistant is built to add and edit records in bulk inside Airtable. Use them where they fit. What they do not give you is the work between fields and tables, the grep, the variant inventory, the script across 12,000 files, or a word-level diff of every change with a per-record way back after publish.

Does this work at 12,000 rows?

Yes. Files are the shape that scales: the inventory is one grep, the mechanical mapping is one script, and the agent works without run caps or rate limits because nothing it touches is live. Review scales by batching. Pull one table, clear the unambiguous diffs first, and spend your reading on the flagged rows. Write-back then runs at the API's pace, one approved record at a time.

Do I need to be technical?

No. The agent writes its own scripts; you write the brief in plain English and read the diffs. Reviewing is a tracked-changes view with approve and reject per record. Validators are optional, for when the cleanup becomes a routine.

See it on your own base

The fastest way to trust it is to watch it run on your data. See it run on your Airtable base →, or download Scratch free and pull one table this afternoon. The Status inventory takes the agent about a minute, and the option list will tell you the rest.

See it run on your own content.

Curtis runs these calls himself. Thirty minutes, no pitch, no slides. He connects your platforms live and shows you your content as an editable, reviewable diff. Bring anything sticky: a refresh, a migration, or a rebrand.

See it run on your content → or download it free