Airtable API
Manage bases, tables, records, and comments in Airtable.
Official docs:
https://airtable.com/developers/web/api/introduction
When to Use
- List and inspect Airtable bases and tables
- Read, create, update, and delete records
- Manage table schemas (fields, views)
- Read and write record comments
- Get current user info
Core APIs
Get Current User
curl -s "https://api.airtable.com/v0/meta/whoami" --header "Authorization: Bearer $(printenv AIRTABLE_TOKEN)" | jq .
List Bases
curl -s "https://api.airtable.com/v0/meta/bases" --header "Authorization: Bearer $(printenv AIRTABLE_TOKEN)" | jq '.bases[] | {id, name, permissionLevel}'
Get Base Schema (List Tables)
Replace <base-id> with your actual base ID (starts with app):
curl -s "https://api.airtable.com/v0/meta/bases/<base-id>/tables" --header "Authorization: Bearer $(printenv AIRTABLE_TOKEN)" | jq '.tables[] | {id, name, fields: [.fields[] | {id, name, type}]}'
List Records
Replace <base-id> and <table-id-or-name> with actual values. Table name must be URL-encoded if it contains spaces.
curl -s "https://api.airtable.com/v0/<base-id>/<table-id-or-name>?maxRecords=10" --header "Authorization: Bearer $(printenv AIRTABLE_TOKEN)" | jq '.records[] | {id, fields, createdTime}'
List Records with Field Selection
curl -s "https://api.airtable.com/v0/<base-id>/<table-id-or-name>?maxRecords=10&fields%5B%5D=Name&fields%5B%5D=Status" --header "Authorization: Bearer $(printenv AIRTABLE_TOKEN)" | jq '.records[] | {id, fields}'
Get a Single Record
curl -s "https://api.airtable.com/v0/<base-id>/<table-id-or-name>/<record-id>" --header "Authorization: Bearer $(printenv AIRTABLE_TOKEN)" | jq .
Create Records
Write the request body to a temp file, then send it:
cat > /tmp/request.json << 'BODY'
{
"records": [
{
"fields": {
"Name": "New Record",
"Status": "Todo"
}
}
]
}
BODY
curl -s -X POST "https://api.airtable.com/v0/<base-id>/<table-id-or-name>" --header "Authorization: Bearer $(printenv AIRTABLE_TOKEN)" --header "Content-Type: application/json" -d @/tmp/request.json | jq '.records[] | {id, fields}'
Update Records (PATCH)
PATCH updates only the specified fields, leaving others unchanged:
cat > /tmp/request.json << 'BODY'
{
"records": [
{
"id": "<record-id>",
"fields": {
"Status": "Done"
}
}
]
}
BODY
curl -s -X PATCH "https://api.airtable.com/v0/<base-id>/<table-id-or-name>" --header "Authorization: Bearer $(printenv AIRTABLE_TOKEN)" --header "Content-Type: application/json" -d @/tmp/request.json | jq '.records[] | {id, fields}'
Delete Records
curl -s -X DELETE "https://api.airtable.com/v0/<base-id>/<table-id-or-name>?records%5B%5D=<record-id>" --header "Authorization: Bearer $(printenv AIRTABLE_TOKEN)" | jq .
List Record Comments
curl -s "https://api.airtable.com/v0/<base-id>/<table-id-or-name>/<record-id>/comments" --header "Authorization: Bearer $(printenv AIRTABLE_TOKEN)" | jq '.comments[] | {id, author, text, createdTime}'
Add a Comment to a Record
cat > /tmp/request.json << 'BODY'
{
"text": "This is a comment added via the API."
}
BODY
curl -s -X POST "https://api.airtable.com/v0/<base-id>/<table-id-or-name>/<record-id>/comments" --header "Authorization: Bearer $(printenv AIRTABLE_TOKEN)" --header "Content-Type: application/json" -d @/tmp/request.json | jq .
Create a Table
cat > /tmp/request.json << 'BODY'
{
"name": "New Table",
"fields": [
{"name": "Name", "type": "singleLineText"},
{"name": "Notes", "type": "multilineText"},
{"name": "Status", "type": "singleSelect", "options": {"choices": [{"name": "Todo"}, {"name": "In Progress"}, {"name": "Done"}]}}
]
}
BODY
curl -s -X POST "https://api.airtable.com/v0/meta/bases/<base-id>/tables" --header "Authorization: Bearer $(printenv AIRTABLE_TOKEN)" --header "Content-Type: application/json" -d @/tmp/request.json | jq '{id, name, fields: [.fields[] | {id, name, type}]}'
Guidelines
- Base IDs start with
app, table IDs start withtbl, record IDs start withrec, field IDs start withfld. - Use
maxRecordsparameter to limit results. Default returns up to 100 records. - For pagination, use the
offsetvalue from the response in the next request. - URL-encode table names that contain spaces (e.g.,
My%20Table). Using table IDs avoids this issue. - The create/update endpoints accept up to 10 records per request.
- Field names are case-sensitive and must match exactly.
- Use PATCH for partial updates (only specified fields change) and PUT for full replacement.