Airtable Participants
by @austinmao
Read and query retreat participant data from the Ceremonia Airtable base. Use this skill when asked about participants, subscriber counts, retreat attendance...
clawhub install airtable-participantsπ About This Skill
name: airtable-participants description: > Read and query retreat participant data from the Ceremonia Airtable base. Use this skill when asked about participants, subscriber counts, retreat attendance, contact segments, phone numbers, emails, or donation status. Also used by other skills (email-newsletter, sms-outreach) to retrieve recipient lists. Read-only by default. version: 1.0.0 metadata: openclaw: requires: env: - AIRTABLE_API_KEY bins: - curl - jq primaryEnv: AIRTABLE_API_KEY emoji: "contacts" homepage: https://airtable.com/developers/web/api/introduction
Airtable Participants Skill
Purpose
Query retreat participant data from the Ceremonia Airtable base. This is the authoritative source of truth for who receives emails and SMS messages. Access is read-only by default β record modifications require Austin's explicit instruction per change.
Required Setup
Ensure AIRTABLE_API_KEY is set in .env.
You will also need:
Store confirmed values in TOOLS.md and MEMORY.md once verified.
Expected Data Structure
Participant records are expected to have at minimum these fields:
| Field | Type | Description | |-------|------|-------------| | name | Text | Full name | | email | Email | Primary email address | | phone | Phone | E.164 format preferred (+1XXXXXXXXXX) | | retreat_status | Select | e.g., active, alumni, prospective, unsubscribed | | tags | Multi-select | e.g., february-2026, guide-circle, donor | | last_contact | Date | Most recent outreach date | | donation_status | Select | e.g., donor, non-donor |
[VERIFY actual field names with Austin on first use β update this section when confirmed]
Common Query Patterns
Get all active participants (for newsletter sends)
curl -s "https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}?filterByFormula={retreat_status}='active'&fields[]=name&fields[]=email" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | jq '.records[].fields'
Get participants with phone numbers (for SMS campaigns)
curl -s "https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}?filterByFormula=AND({retreat_status}='active',{phone}!='')&fields[]=name&fields[]=phone" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | jq '.records[].fields'
Get participant count by status
curl -s "https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}?fields[]=retreat_status" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | jq '[.records[].fields.retreat_status] | group_by(.) | map({status: .[0], count: length})'
Get participants by tag
curl -s "https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}?filterByFormula=FIND('february-2026',ARRAYJOIN({tags}))" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | jq '.records[].fields'
Note: Airtable paginates at 100 records. Use the offset parameter from the response to fetch subsequent pages:
curl -s "https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}?offset={OFFSET_TOKEN}" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | jq .
Always paginate fully before reporting totals or building recipient lists.Behavior Rules
Record Modification (Requires Austin Approval)
When Austin instructs a record change (e.g., marking someone unsubscribed, updating last_contact): 1. Confirm the specific change with Austin before executing 2. Execute the PATCH request 3. Log the change in memory/logs/crm-writes/YYYY-MM-DD.md with: record name/email, field changed, old value, new value, Austin's instruction timestamp