Uses Airtable's native upsert (PATCH with performUpsert) to create or
update records based on merge fields. Supports two matching modes:
Arguments
- data
A data frame of records to upsert. May include an
airtable_idcolumn for direct record matching. Computed field columns and attachment field columns are silently dropped from the record payload.- table
Table name or ID.
- merge_on
Character vector of 1-3 field names to match on (for records without an
airtable_id).- base_id
Base ID (e.g.,
"appXXXXXX"). IfNULL, uses the session default set byair_set_base()or theAIRTABLE_BASE_IDenvironment variable.- typecast
If
TRUE(default), Airtable will attempt to coerce values.- add_fields
What to do when
datacontains columns not in the table:"error"(default): error if unknown columns exist."warn": warn and drop unknown columns."yes": create missing fields before upserting (assingleLineText).
- attachments
How to handle attachment fields:
"meta"(default) keeps only metadata (filename, url, size, type);"file"downloads toattachment_dir;"blob"downloads as in-memory raw vectors.- attachment_dir
Directory for downloading attachments (required when
attachments = "file"). Files are saved as{attachment_dir}/{record_id}/{filename}.- progress
Logical or
NULL. IfTRUE, shows a cli progress bar for batch operations. IfNULL(default), uses optionairtable2.progress.baror env varAIRTABLE2_PROGRESS_BAR.- .token
Personal access token (resolved via
air_token()ifNULL).
Details
If
datacontains anairtable_idcolumn, records with non-NA IDs are updated directly by record ID (more efficient).Records without an
airtable_id(or where it isNA) are matched using themerge_onfield(s) via Airtable's upsert mechanism.
Computed fields (formulas, rollups, autoNumber, createdTime,
lastModifiedTime, etc.) and attachment fields are automatically excluded
from the upload payload. When attachments is "file" or "blob",
attachment content is uploaded separately after record creation/update.
Optionally creates missing columns.
Examples
if (FALSE) { # \dontrun{
data <- data.frame(Name = c("Alice", "Bob"), Age = c(31, 26))
result <- air_upsert(data, "Contacts", merge_on = "Name", base_id = "appXXXXXX")
result$created
result$updated
} # }