{
  "schemaVersion": "1.0",
  "item": {
    "slug": "airtable-participants",
    "name": "Airtable Participants",
    "source": "tencent",
    "type": "skill",
    "category": "数据分析",
    "sourceUrl": "https://clawhub.ai/austinmao/airtable-participants",
    "canonicalUrl": "https://clawhub.ai/austinmao/airtable-participants",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/airtable-participants",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=airtable-participants",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-23T16:43:11.935Z",
      "expiresAt": "2026-04-30T16:43:11.935Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
        "contentDisposition": "attachment; filename=\"4claw-imageboard-1.0.1.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/airtable-participants"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/airtable-participants",
    "agentPageUrl": "https://openagent3.xyz/skills/airtable-participants/agent",
    "manifestUrl": "https://openagent3.xyz/skills/airtable-participants/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/airtable-participants/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Purpose",
        "body": "Query retreat participant data from the Ceremonia Airtable base. This is the\nauthoritative source of truth for who receives emails and SMS messages.\nAccess is read-only by default — record modifications require Austin's\nexplicit instruction per change."
      },
      {
        "title": "Required Setup",
        "body": "Ensure AIRTABLE_API_KEY is set in .env.\n\nYou will also need:\n\nBase ID: [VERIFY — find in Airtable API docs at airtable.com/developers or ask Austin]\nTable name: [VERIFY — confirm the participant table name with Austin]\n\nStore confirmed values in TOOLS.md and MEMORY.md once verified."
      },
      {
        "title": "Expected Data Structure",
        "body": "Participant records are expected to have at minimum these fields:\n\nFieldTypeDescriptionnameTextFull nameemailEmailPrimary email addressphonePhoneE.164 format preferred (+1XXXXXXXXXX)retreat_statusSelecte.g., active, alumni, prospective, unsubscribedtagsMulti-selecte.g., february-2026, guide-circle, donorlast_contactDateMost recent outreach datedonation_statusSelecte.g., donor, non-donor\n\n[VERIFY actual field names with Austin on first use — update this section when confirmed]"
      },
      {
        "title": "Get all active participants (for newsletter sends)",
        "body": "curl -s \"https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}?filterByFormula={retreat_status}='active'&fields[]=name&fields[]=email\" \\\n  -H \"Authorization: Bearer $AIRTABLE_API_KEY\" | jq '.records[].fields'"
      },
      {
        "title": "Get participants with phone numbers (for SMS campaigns)",
        "body": "curl -s \"https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}?filterByFormula=AND({retreat_status}='active',{phone}!='')&fields[]=name&fields[]=phone\" \\\n  -H \"Authorization: Bearer $AIRTABLE_API_KEY\" | jq '.records[].fields'"
      },
      {
        "title": "Get participant count by status",
        "body": "curl -s \"https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}?fields[]=retreat_status\" \\\n  -H \"Authorization: Bearer $AIRTABLE_API_KEY\" | jq '[.records[].fields.retreat_status] | group_by(.) | map({status: .[0], count: length})'"
      },
      {
        "title": "Get participants by tag",
        "body": "curl -s \"https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}?filterByFormula=FIND('february-2026',ARRAYJOIN({tags}))\" \\\n  -H \"Authorization: Bearer $AIRTABLE_API_KEY\" | jq '.records[].fields'\n\nNote: Airtable paginates at 100 records. Use the offset parameter from the response to fetch subsequent pages:\n\ncurl -s \"https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}?offset={OFFSET_TOKEN}\" \\\n  -H \"Authorization: Bearer $AIRTABLE_API_KEY\" | jq .\n\nAlways paginate fully before reporting totals or building recipient lists."
      },
      {
        "title": "Behavior Rules",
        "body": "Read-only by default — never PATCH, POST, or DELETE Airtable records without Austin's explicit instruction per operation\nWhen building a recipient list for email or SMS: always filter out records where retreat_status is 'unsubscribed'\nNever include email addresses or phone numbers in Slack messages — summarize counts and segments only\nIf a query returns 0 results unexpectedly: report the issue to Austin rather than sending to an empty list\nPaginate all list queries fully — do not report partial counts or build partial recipient lists\nIf Airtable API returns an error: surface it to Austin immediately with the error code and message"
      },
      {
        "title": "Record Modification (Requires Austin Approval)",
        "body": "When Austin instructs a record change (e.g., marking someone unsubscribed, updating last_contact):\n\nConfirm the specific change with Austin before executing\nExecute the PATCH request\nLog 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"
      },
      {
        "title": "Example Invocations",
        "body": "\"How many active participants do we have?\"\n\"Get the email list for the February retreat attendees\"\n\"Who attended the last three retreats?\"\n\"How many people have phone numbers in the system?\"\n\"Mark [name] as unsubscribed\" (requires Austin approval)\n\"Pull the full active participant list for the newsletter\"\n\"How many people joined since January?\""
      }
    ],
    "body": "Airtable Participants Skill\nPurpose\n\nQuery 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.\n\nRequired Setup\n\nEnsure AIRTABLE_API_KEY is set in .env.\n\nYou will also need:\n\nBase ID: [VERIFY — find in Airtable API docs at airtable.com/developers or ask Austin]\nTable name: [VERIFY — confirm the participant table name with Austin]\n\nStore confirmed values in TOOLS.md and MEMORY.md once verified.\n\nExpected Data Structure\n\nParticipant records are expected to have at minimum these fields:\n\nField\tType\tDescription\nname\tText\tFull name\nemail\tEmail\tPrimary email address\nphone\tPhone\tE.164 format preferred (+1XXXXXXXXXX)\nretreat_status\tSelect\te.g., active, alumni, prospective, unsubscribed\ntags\tMulti-select\te.g., february-2026, guide-circle, donor\nlast_contact\tDate\tMost recent outreach date\ndonation_status\tSelect\te.g., donor, non-donor\n\n[VERIFY actual field names with Austin on first use — update this section when confirmed]\n\nCommon Query Patterns\nGet all active participants (for newsletter sends)\ncurl -s \"https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}?filterByFormula={retreat_status}='active'&fields[]=name&fields[]=email\" \\\n  -H \"Authorization: Bearer $AIRTABLE_API_KEY\" | jq '.records[].fields'\n\nGet participants with phone numbers (for SMS campaigns)\ncurl -s \"https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}?filterByFormula=AND({retreat_status}='active',{phone}!='')&fields[]=name&fields[]=phone\" \\\n  -H \"Authorization: Bearer $AIRTABLE_API_KEY\" | jq '.records[].fields'\n\nGet participant count by status\ncurl -s \"https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}?fields[]=retreat_status\" \\\n  -H \"Authorization: Bearer $AIRTABLE_API_KEY\" | jq '[.records[].fields.retreat_status] | group_by(.) | map({status: .[0], count: length})'\n\nGet participants by tag\ncurl -s \"https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}?filterByFormula=FIND('february-2026',ARRAYJOIN({tags}))\" \\\n  -H \"Authorization: Bearer $AIRTABLE_API_KEY\" | jq '.records[].fields'\n\n\nNote: Airtable paginates at 100 records. Use the offset parameter from the response to fetch subsequent pages:\n\ncurl -s \"https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}?offset={OFFSET_TOKEN}\" \\\n  -H \"Authorization: Bearer $AIRTABLE_API_KEY\" | jq .\n\n\nAlways paginate fully before reporting totals or building recipient lists.\n\nBehavior Rules\nRead-only by default — never PATCH, POST, or DELETE Airtable records without Austin's explicit instruction per operation\nWhen building a recipient list for email or SMS: always filter out records where retreat_status is 'unsubscribed'\nNever include email addresses or phone numbers in Slack messages — summarize counts and segments only\nIf a query returns 0 results unexpectedly: report the issue to Austin rather than sending to an empty list\nPaginate all list queries fully — do not report partial counts or build partial recipient lists\nIf Airtable API returns an error: surface it to Austin immediately with the error code and message\nRecord Modification (Requires Austin Approval)\n\nWhen Austin instructs a record change (e.g., marking someone unsubscribed, updating last_contact):\n\nConfirm the specific change with Austin before executing\nExecute the PATCH request\nLog 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\nExample Invocations\n\"How many active participants do we have?\"\n\"Get the email list for the February retreat attendees\"\n\"Who attended the last three retreats?\"\n\"How many people have phone numbers in the system?\"\n\"Mark [name] as unsubscribed\" (requires Austin approval)\n\"Pull the full active participant list for the newsletter\"\n\"How many people joined since January?\""
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/austinmao/airtable-participants",
    "publisherUrl": "https://clawhub.ai/austinmao/airtable-participants",
    "owner": "austinmao",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/airtable-participants",
    "downloadUrl": "https://openagent3.xyz/downloads/airtable-participants",
    "agentUrl": "https://openagent3.xyz/skills/airtable-participants/agent",
    "manifestUrl": "https://openagent3.xyz/skills/airtable-participants/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/airtable-participants/agent.md"
  }
}