| name | airtable |
| description | Access Airtable bases, tables, and records. Query data, search records, and read structured information. |
Airtable Integration
This skill provides access to Airtable bases and tables via the Airtable REST API.
Setup Required
Create a Personal Access Token:
- Go to https://airtable.com/create/tokens
- Click "Create new token"
- Give it a name (e.g., "Claude Code")
- Add scopes:
data.records:read- Read recordsschema.bases:read- Read base schema
- Add access to the bases you want to query
- Create and copy the token
Set the token as an environment variable:
export AIRTABLE_TOKEN="pat..."
When to Use
Use this skill when the user:
- Asks about data stored in Airtable
- Wants to query or search Airtable records
- Needs to look up information in a base
- Mentions "Airtable" or specific base/table names
API Endpoints
Base URL: https://api.airtable.com/v0
All requests need:
-H "Authorization: Bearer $(printenv AIRTABLE_TOKEN)"
List Bases
Get All Bases:
curl -s "https://api.airtable.com/v0/meta/bases" \
-H "Authorization: Bearer $(printenv AIRTABLE_TOKEN)" | jq '.bases[] | {name, id}'
Get Base Schema
Get Tables and Fields:
curl -s "https://api.airtable.com/v0/meta/bases/{BASE_ID}/tables" \
-H "Authorization: Bearer $(printenv AIRTABLE_TOKEN)"
List Records
Get Records from Table:
curl -s "https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}" \
-H "Authorization: Bearer $(printenv AIRTABLE_TOKEN)"
With Pagination:
curl -s "https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}?pageSize=100" \
-H "Authorization: Bearer $(printenv AIRTABLE_TOKEN)"
Filter Records
Using Formula Filter:
curl -s -G "https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}" \
--data-urlencode "filterByFormula={Status}='Active'" \
-H "Authorization: Bearer $(printenv AIRTABLE_TOKEN)"
Multiple Conditions:
curl -s -G "https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}" \
--data-urlencode "filterByFormula=AND({Status}='Active', {Priority}='High')" \
-H "Authorization: Bearer $(printenv AIRTABLE_TOKEN)"
Sort Records
curl -s -G "https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}" \
--data-urlencode "sort[0][field]=Created" \
--data-urlencode "sort[0][direction]=desc" \
-H "Authorization: Bearer $(printenv AIRTABLE_TOKEN)"
Select Specific Fields
curl -s -G "https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}" \
--data-urlencode "fields[]=Name" \
--data-urlencode "fields[]=Status" \
--data-urlencode "fields[]=Due Date" \
-H "Authorization: Bearer $(printenv AIRTABLE_TOKEN)"
Get Single Record
curl -s "https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}/{RECORD_ID}" \
-H "Authorization: Bearer $(printenv AIRTABLE_TOKEN)"
Formula Syntax
Airtable formulas for filtering:
| Formula | Description |
|---|---|
{Field}='Value' |
Exact match |
{Field}!='Value' |
Not equal |
FIND('text', {Field}) |
Contains text |
{Field}>100 |
Numeric comparison |
IS_AFTER({Date}, '2024-01-01') |
Date after |
IS_BEFORE({Date}, '2024-01-01') |
Date before |
{Checkbox}=TRUE() |
Checkbox is checked |
{Field}=BLANK() |
Field is empty |
AND(cond1, cond2) |
Both conditions |
OR(cond1, cond2) |
Either condition |
NOT(condition) |
Negation |
Common Workflows
List All Bases
curl -s "https://api.airtable.com/v0/meta/bases" \
-H "Authorization: Bearer $(printenv AIRTABLE_TOKEN)" | jq '.bases[] | {name, id}'
Explore a Base's Structure
BASE_ID="appXXXXXXXX"
curl -s "https://api.airtable.com/v0/meta/bases/${BASE_ID}/tables" \
-H "Authorization: Bearer $(printenv AIRTABLE_TOKEN)" | jq '.tables[] | {name, id, fields: [.fields[].name]}'
Get Recent Records
BASE_ID="appXXXXXXXX"
TABLE="Tasks"
curl -s -G "https://api.airtable.com/v0/${BASE_ID}/${TABLE}" \
--data-urlencode "sort[0][field]=Created" \
--data-urlencode "sort[0][direction]=desc" \
--data-urlencode "pageSize=10" \
-H "Authorization: Bearer $(printenv AIRTABLE_TOKEN)" | jq '.records[] | .fields'
Search for Records
BASE_ID="appXXXXXXXX"
TABLE="Contacts"
curl -s -G "https://api.airtable.com/v0/${BASE_ID}/${TABLE}" \
--data-urlencode "filterByFormula=FIND('John', {Name})" \
-H "Authorization: Bearer $(printenv AIRTABLE_TOKEN)"
Filter by Status
curl -s -G "https://api.airtable.com/v0/${BASE_ID}/${TABLE}" \
--data-urlencode "filterByFormula={Status}='In Progress'" \
-H "Authorization: Bearer $(printenv AIRTABLE_TOKEN)" | jq '.records[] | {name: .fields.Name, status: .fields.Status}'
Finding Base and Table IDs
Base ID: Found in the Airtable URL: https://airtable.com/{BASE_ID}/...
- Starts with
app
Table Name: Use the exact table name from Airtable (URL-encode spaces)
- Or use table ID (starts with
tbl) from the schema endpoint
Record ID: Starts with rec, found in record URLs or API responses
Pagination
Responses are paginated (max 100 records per request). Use the offset parameter:
# First request
curl -s "https://api.airtable.com/v0/${BASE_ID}/${TABLE}?pageSize=100" \
-H "Authorization: Bearer $(printenv AIRTABLE_TOKEN)"
# If response includes "offset", use it for next page
curl -s "https://api.airtable.com/v0/${BASE_ID}/${TABLE}?pageSize=100&offset={OFFSET_FROM_RESPONSE}" \
-H "Authorization: Bearer $(printenv AIRTABLE_TOKEN)"
Notes
- Rate limit: 5 requests/second per base
- Max 100 records per request
- Field names are case-sensitive
- URL-encode table names with spaces
- Linked records return record IDs; fetch separately if needed
- Attachments return URLs that expire