claude/skills/airtable/SKILL.md
Access Airtable bases, tables, and records. Query data, search records, and read structured information.
npx skillsauth add tbroadley/dotfiles airtableInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill provides access to Airtable bases and tables via the Airtable REST API.
Create a Personal Access Token:
data.records:read - Read recordsschema.bases:read - Read base schemaSet the token as an environment variable:
export AIRTABLE_TOKEN="pat..."
Use this skill when the user:
Base URL: https://api.airtable.com/v0
All requests need:
-H "Authorization: Bearer $(printenv AIRTABLE_TOKEN)"
Get All Bases:
curl -s "https://api.airtable.com/v0/meta/bases" \
-H "Authorization: Bearer $(printenv AIRTABLE_TOKEN)" | jq '.bases[] | {name, id}'
Get Tables and Fields:
curl -s "https://api.airtable.com/v0/meta/bases/{BASE_ID}/tables" \
-H "Authorization: Bearer $(printenv AIRTABLE_TOKEN)"
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)"
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)"
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)"
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)"
curl -s "https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}/{RECORD_ID}" \
-H "Authorization: Bearer $(printenv AIRTABLE_TOKEN)"
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 |
curl -s "https://api.airtable.com/v0/meta/bases" \
-H "Authorization: Bearer $(printenv AIRTABLE_TOKEN)" | jq '.bases[] | {name, id}'
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]}'
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'
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)"
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}'
Base ID: Found in the Airtable URL: https://airtable.com/{BASE_ID}/...
appTable Name: Use the exact table name from Airtable (URL-encode spaces)
tbl) from the schema endpointRecord ID: Starts with rec, found in record URLs or API responses
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)"
tools
Add words to the Wispr Flow dictionary. Use when the user wants to add a word, phrase, or snippet to Wispr Flow for voice dictation.
documentation
Upload images to a GitHub PR description or comment using a shared gist as image hosting. Use when the user wants to add plots, screenshots, or other images to a PR.
testing
Manage tasks, projects, and productivity in Todoist. View tasks, add new items, check completed work, and organize projects.
data-ai
Use when working with stacked diffs (branch B based on branch A, which is based on main).