Skill: lucassynnott/fathom (version 1.0.0)

--- name: fathom description: Connect to Fathom AI to fetch call recordings, transcripts, and summaries. Use when user asks about their meetings, call history, or wants to search past conversations. read_when: - User asks about their Fathom calls or meetings - User wants to search call transcripts - User needs a call summary or action items - User wants to set up Fathom integration metadata: clawdbot: emoji: "📞" requires: bins: ["curl", "jq"] --- # Fathom Skill Connect to [Fathom AI](https://fathom.video) to fetch call recordings, transcripts, and summaries. ## Setup ### 1. Get Your API Key 1. Go to [developers.fathom.ai](https://developers.fathom.ai) 2. Create an API key 3. Copy the key (format: `v1XDx...`) ### 2. Configure ```bash # Option A: Store in file (recommended) echo "YOUR_API_KEY" > ~/.fathom_api_key chmod 600 ~/.fathom_api_key # Option B: Environment variable export FATHOM_API_KEY="YOUR_API_KEY" ``` ### 3. Test Connection ```bash ./scripts/setup.sh ``` --- ## Commands ### List Recent Calls ```bash ./scripts/list-calls.sh # Last 10 calls ./scripts/list-calls.sh --limit 20 # Last 20 calls ./scripts/list-calls.sh --after 2026-01-01 # Calls after date ./scripts/list-calls.sh --json # Raw JSON output ``` ### Get Transcript ```bash ./scripts/get-transcript.sh 123456789 # By recording ID ./scripts/get-transcript.sh 123456789 --json ./scripts/get-transcript.sh 123456789 --text-only ``` ### Get Summary ```bash ./scripts/get-summary.sh 123456789 # By recording ID ./scripts/get-summary.sh 123456789 --json ``` ### Search Calls ```bash ./scripts/search-calls.sh "product launch" # Search transcripts ./scripts/search-calls.sh --speaker "Lucas" ./scripts/search-calls.sh --after 2026-01-01 --before 2026-01-15 ``` --- ## API Reference | Endpoint | Method | Description | |----------|--------|-------------| | `/meetings` | GET | List meetings with filters | | `/recordings/{id}/transcript` | GET | Full transcript with speakers | | `/recordings/{id}/summary` | GET | AI summary + action items | | `/webhooks` | POST | Register webhook for auto-sync | **Base URL:** `https://api.fathom.ai/external/v1` **Auth:** `X-API-Key` header --- ## Filters for list-calls | Filter | Description | Example | |--------|-------------|---------| | `--limit N` | Number of results | `--limit 20` | | `--after DATE` | Calls after date | `--after 2026-01-01` | | `--before DATE` | Calls before date | `--before 2026-01-15` | | `--cursor TOKEN` | Pagination cursor | `--cursor eyJo...` | --- ## Output Formats | Flag | Description | |------|-------------| | `--json` | Raw JSON from API | | `--table` | Formatted table (default for lists) | | `--text-only` | Plain text (transcripts only) | --- ## Examples ### Get your last call's summary ```bash # Get latest call ID CALL_ID=$(./scripts/list-calls.sh --limit 1 --json | jq -r '.[0].recording_id') # Get summary ./scripts/get-summary.sh $CALL_ID ``` ### Export all calls from last week ```bash ./scripts/list-calls.sh --after $(date -d '7 days ago' +%Y-%m-%d) --json > last_week_calls.json ``` ### Find calls mentioning a topic ```bash ./scripts/search-calls.sh "quarterly review" ``` --- ## Troubleshooting | Error | Solution | |-------|----------| | "No API key found" | Run setup or set `FATHOM_API_KEY` | | "401 Unauthorized" | Check API key is valid | | "429 Rate Limited" | Wait and retry | | "Recording not found" | Verify recording ID exists | --- ## Webhook Setup (Advanced) For automatic transcript ingestion, see the webhook setup guide: ```bash ./scripts/setup-webhook.sh --url https://your-endpoint.com/webhook ``` Requires a publicly accessible HTTPS endpoint.

path: examples/config-snippet.json
content: {
  "_comment": "Add to your clawdbot.json or use environment variables",
  
  "fathom": {
    "apiKey": "YOUR_FATHOM_API_KEY"
  },
  
  "_alternative": "Or set environment variable: FATHOM_API_KEY=your_key",
  "_file": "Or store in file: ~/.fathom_api_key"
}


path: scripts/get-summary.sh
content: #!/bin/bash
# Get Fathom call summary

set -e

OUTPUT="markdown"
RECORDING_ID=""

# Get API key
get_api_key() {
    if [ -n "$FATHOM_API_KEY" ]; then
        echo "$FATHOM_API_KEY"
    elif [ -f ~/.fathom_api_key ]; then
        cat ~/.fathom_api_key
    else
        echo ""
    fi
}

# Parse arguments
while [[ $# -gt 0 ]]; do
    case $1 in
        --json) OUTPUT="json"; shift ;;
        -h|--help)
            echo "Usage: get-summary.sh <recording_id> [options]"
            echo ""
            echo "Options:"
            echo "  --json  Raw JSON output"
            exit 0
            ;;
        *)
            if [ -z "$RECORDING_ID" ]; then
                RECORDING_ID="$1"
            else
                echo "Unknown option: $1"
                exit 1
            fi
            shift
            ;;
    esac
done

if [ -z "$RECORDING_ID" ]; then
    echo "Usage: get-summary.sh <recording_id>"
    echo "Run ./scripts/list-calls.sh to find recording IDs"
    exit 1
fi

[REDACTED_SECRET])
if [ -z "$API_KEY" ]; then
    echo "❌ No API key. Run ./scripts/setup.sh first."
    exit 1
fi

# Fetch summary
RESPONSE=$(curl -s -w "\n%{http_code}" \
    -H "X-[REDACTED_SECRET]" \
    "https://api.fathom.ai/external/v1/recordings/$RECORDING_ID/summary")

HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | sed '$d')

if [ "$HTTP_CODE" != "200" ]; then
    if [ "$HTTP_CODE" = "404" ]; then
        echo "❌ Recording $RECORDING_ID not found"
    else
        echo "❌ Error (HTTP $HTTP_CODE)"
        echo "$BODY" | jq -r '.error // .' 2>/dev/null || echo "$BODY"
    fi
    exit 1
fi

# Output
if [ "$OUTPUT" = "json" ]; then
    echo "$BODY" | jq '.'
else
    # Markdown format
    SUMMARY=$(echo "$BODY" | jq -r '.summary // "No summary available"')
    ACTION_ITEMS=$(echo "$BODY" | jq -r '.action_items // []')
    
    echo "# Call Summary"
    echo ""
    echo "$SUMMARY"
    
    if [ "$ACTION_ITEMS" != "[]" ] && [ "$ACTION_ITEMS" != "null" ]; then
        echo ""
        echo "## Action Items"
        echo ""
        echo "$ACTION_ITEMS" | jq -r '.[] | "- \(.)"' 2>/dev/null || echo "$ACTION_ITEMS"
    fi
fi


path: scripts/get-transcript.sh
content: #!/bin/bash
# Get Fathom call transcript

set -e

OUTPUT="markdown"
RECORDING_ID=""

# Get API key
get_api_key() {
    if [ -n "$FATHOM_API_KEY" ]; then
        echo "$FATHOM_API_KEY"
    elif [ -f ~/.fathom_api_key ]; then
        cat ~/.fathom_api_key
    else
        echo ""
    fi
}

# Parse arguments
while [[ $# -gt 0 ]]; do
    case $1 in
        --json) OUTPUT="json"; shift ;;
        --text-only) OUTPUT="text"; shift ;;
        -h|--help)
            echo "Usage: get-transcript.sh <recording_id> [options]"
            echo ""
            echo "Options:"
            echo "  --json       Raw JSON output"
            echo "  --text-only  Plain text without speakers"
            exit 0
            ;;
        *)
            if [ -z "$RECORDING_ID" ]; then
                RECORDING_ID="$1"
            else
                echo "Unknown option: $1"
                exit 1
            fi
            shift
            ;;
    esac
done

if [ -z "$RECORDING_ID" ]; then
    echo "Usage: get-transcript.sh <recording_id>"
    echo "Run ./scripts/list-calls.sh to find recording IDs"
    exit 1
fi

[REDACTED_SECRET])
if [ -z "$API_KEY" ]; then
    echo "❌ No API key. Run ./scripts/setup.sh first."
    exit 1
fi

# Fetch transcript
RESPONSE=$(curl -s -w "\n%{http_code}" \
    -H "X-[REDACTED_SECRET]" \
    "https://api.fathom.ai/external/v1/recordings/$RECORDING_ID/transcript")

HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | sed '$d')

if [ "$HTTP_CODE" != "200" ]; then
    if [ "$HTTP_CODE" = "404" ]; then
        echo "❌ Recording $RECORDING_ID not found"
    else
        echo "❌ Error (HTTP $HTTP_CODE)"
        echo "$BODY" | jq -r '.error // .' 2>/dev/null || echo "$BODY"
    fi
    exit 1
fi

# Output
case $OUTPUT in
    json)
        echo "$BODY" | jq '.'
        ;;
    text)
        echo "$BODY" | jq -r '.transcript[].text' | tr '\n' ' ' | fold -s -w 80
        echo ""
        ;;
    markdown)
        echo "# Transcript"
        echo ""
        echo "$BODY" | jq -r '.transcript[] | "**\(.speaker.display_name // "Unknown")** (\(.timestamp // "")):\n\(.text)\n"'
        ;;
esac


path: scripts/list-calls.sh
content: #!/bin/bash
# List Fathom calls with filters

set -e

# Defaults
LIMIT=10
OUTPUT="table"
AFTER=""
BEFORE=""
CURSOR=""

# Get API key
get_api_key() {
    if [ -n "$FATHOM_API_KEY" ]; then
        echo "$FATHOM_API_KEY"
    elif [ -f ~/.fathom_api_key ]; then
        cat ~/.fathom_api_key
    else
        echo ""
    fi
}

# Parse arguments
while [[ $# -gt 0 ]]; do
    case $1 in
        --limit) LIMIT="$2"; shift 2 ;;
        --after) AFTER="$2"; shift 2 ;;
        --before) BEFORE="$2"; shift 2 ;;
        --cursor) CURSOR="$2"; shift 2 ;;
        --json) OUTPUT="json"; shift ;;
        --table) OUTPUT="table"; shift ;;
        -h|--help)
            echo "Usage: list-calls.sh [options]"
            echo ""
            echo "Options:"
            echo "  --limit N      Number of results (default: 10)"
            echo "  --after DATE   Calls after date (YYYY-MM-DD)"
            echo "  --before DATE  Calls before date (YYYY-MM-DD)"
            echo "  --cursor TOKEN Pagination cursor"
            echo "  --json         Raw JSON output"
            echo "  --table        Formatted table (default)"
            exit 0
            ;;
        *) echo "Unknown option: $1"; exit 1 ;;
    esac
done

[REDACTED_SECRET])
if [ -z "$API_KEY" ]; then
    echo "❌ No API key. Run ./scripts/setup.sh first."
    exit 1
fi

# Build URL with query params
URL="https://api.fathom.ai/external/v1/meetings?limit=$LIMIT"
[ -n "$AFTER" ] && URL="$URL&created_after=${AFTER}T00:00:00Z"
[ -n "$BEFORE" ] && URL="$URL&created_before=${BEFORE}T23:59:59Z"
[ -n "$CURSOR" ] && URL="$URL&cursor=$CURSOR"

# Fetch
RESPONSE=$(curl -s -H "X-[REDACTED_SECRET]" "$URL")

# Check for errors
if echo "$RESPONSE" | jq -e '.error' >/dev/null 2>&1; then
    echo "❌ Error: $(echo "$RESPONSE" | jq -r '.error')"
    exit 1
fi

# Output
if [ "$OUTPUT" = "json" ]; then
    echo "$RESPONSE" | jq '.items'
else
    # Table format
    echo ""
    printf "%-12s | %-40s | %-20s | %s\n" "RECORDING ID" "TITLE" "DATE" "RECORDED BY"
    printf "%s\n" "-------------|------------------------------------------|----------------------|-------------"
    
    echo "$RESPONSE" | jq -r '.items[] | [
        (.recording_id | tostring),
        (.title // "Untitled" | .[0:38]),
        (.created_at | split("T")[0]),
        (.recorded_by.name // "Unknown")
    ] | @tsv' | while IFS=$'\t' read -r id title date recorder; do
        printf "%-12s | %-40s | %-20s | %s\n" "$id" "$title" "$date" "$recorder"
    done
    
    # Pagination info
    NEXT=$(echo "$RESPONSE" | jq -r '.next_cursor // empty')
    if [ -n "$NEXT" ]; then
        echo ""
        echo "More results available. Use: --cursor \"$NEXT\""
    fi
fi


path: scripts/search-calls.sh
content: #!/bin/bash
# Search Fathom calls by various criteria

set -e

QUERY=""
SPEAKER=""
AFTER=""
BEFORE=""
LIMIT=20
OUTPUT="table"

# Get API key
get_api_key() {
    if [ -n "$FATHOM_API_KEY" ]; then
        echo "$FATHOM_API_KEY"
    elif [ -f ~/.fathom_api_key ]; then
        cat ~/.fathom_api_key
    else
        echo ""
    fi
}

# Parse arguments
while [[ $# -gt 0 ]]; do
    case $1 in
        --speaker) SPEAKER="$2"; shift 2 ;;
        --after) AFTER="$2"; shift 2 ;;
        --before) BEFORE="$2"; shift 2 ;;
        --limit) LIMIT="$2"; shift 2 ;;
        --json) OUTPUT="json"; shift ;;
        -h|--help)
            echo "Usage: search-calls.sh [query] [options]"
            echo ""
            echo "Options:"
            echo "  --speaker NAME  Filter by speaker name"
            echo "  --after DATE    Calls after date"
            echo "  --before DATE   Calls before date"
            echo "  --limit N       Max results (default: 20)"
            echo "  --json          Raw JSON output"
            exit 0
            ;;
        *)
            if [ -z "$QUERY" ]; then
                QUERY="$1"
            fi
            shift
            ;;
    esac
done

[REDACTED_SECRET])
if [ -z "$API_KEY" ]; then
    echo "❌ No API key. Run ./scripts/setup.sh first."
    exit 1
fi

# Build URL
URL="https://api.fathom.ai/external/v1/meetings?limit=$LIMIT"
[ -n "$AFTER" ] && URL="$URL&created_after=${AFTER}T00:00:00Z"
[ -n "$BEFORE" ] && URL="$URL&created_before=${BEFORE}T23:59:59Z"

# Fetch meetings
RESPONSE=$(curl -s -H "X-[REDACTED_SECRET]" "$URL")

# Check for errors
if echo "$RESPONSE" | jq -e '.error' >/dev/null 2>&1; then
    echo "❌ Error: $(echo "$RESPONSE" | jq -r '.error')"
    exit 1
fi

# Filter results if query provided
if [ -n "$QUERY" ] || [ -n "$SPEAKER" ]; then
    FILTERED=$(echo "$RESPONSE" | jq --arg q "${QUERY,,}" --arg s "${SPEAKER,,}" '
        .items | map(select(
            (if $q != "" then (.title | ascii_downcase | contains($q)) else true end) and
            (if $s != "" then (.recorded_by.name | ascii_downcase | contains($s)) or 
                (.calendar_invitees[]?.name | ascii_downcase | contains($s)) else true end)
        ))
    ')
else
    FILTERED=$(echo "$RESPONSE" | jq '.items')
fi

# Output
if [ "$OUTPUT" = "json" ]; then
    echo "$FILTERED"
else
    COUNT=$(echo "$FILTERED" | jq 'length')
    
    if [ "$COUNT" = "0" ]; then
        echo "No calls found matching criteria."
        exit 0
    fi
    
    echo "Found $COUNT call(s):"
    echo ""
    printf "%-12s | %-40s | %-12s | %s\n" "RECORDING ID" "TITLE" "DATE" "RECORDED BY"
    printf "%s\n" "-------------|------------------------------------------|--------------|-------------"
    
    echo "$FILTERED" | jq -r '.[] | [
        (.recording_id | tostring),
        (.title // "Untitled" | .[0:38]),
        (.created_at | split("T")[0]),
        (.recorded_by.name // "Unknown")
    ] | @tsv' | while IFS=$'\t' read -r id title date recorder; do
        printf "%-12s | %-40s | %-12s | %s\n" "$id" "$title" "$date" "$recorder"
    done
fi


path: scripts/setup-webhook.sh
content: #!/bin/bash
# Register a Fathom webhook

set -e

WEBHOOK_URL=""
INCLUDE_TRANSCRIPT=true
INCLUDE_SUMMARY=true
INCLUDE_ACTION_ITEMS=true

# Get API key
get_api_key() {
    if [ -n "$FATHOM_API_KEY" ]; then
        echo "$FATHOM_API_KEY"
    elif [ -f ~/.fathom_api_key ]; then
        cat ~/.fathom_api_key
    else
        echo ""
    fi
}

# Parse arguments
while [[ $# -gt 0 ]]; do
    case $1 in
        --url) WEBHOOK_URL="$2"; shift 2 ;;
        --no-transcript) INCLUDE_TRANSCRIPT=false; shift ;;
        --no-summary) INCLUDE_SUMMARY=false; shift ;;
        --no-action-items) INCLUDE_ACTION_ITEMS=false; shift ;;
        -h|--help)
            echo "Usage: setup-webhook.sh --url <https://...> [options]"
            echo ""
            echo "Options:"
            echo "  --url URL           Webhook endpoint (required, must be HTTPS)"
            echo "  --no-transcript     Don't include transcript"
            echo "  --no-summary        Don't include summary"
            echo "  --no-action-items   Don't include action items"
            echo ""
            echo "Requirements:"
            echo "  - URL must be publicly accessible HTTPS endpoint"
            echo "  - Endpoint should accept POST requests with JSON body"
            exit 0
            ;;
        *) echo "Unknown option: $1"; exit 1 ;;
    esac
done

if [ -z "$WEBHOOK_URL" ]; then
    echo "❌ Webhook URL required"
    echo "Usage: setup-webhook.sh --url https://your-domain.com/webhook"
    exit 1
fi

if [[ ! "$WEBHOOK_URL" =~ ^https:// ]]; then
    echo "❌ Webhook URL must be HTTPS"
    exit 1
fi

[REDACTED_SECRET])
if [ -z "$API_KEY" ]; then
    echo "❌ No API key. Run ./scripts/setup.sh first."
    exit 1
fi

echo "📡 Registering webhook..."
echo "   URL: $WEBHOOK_URL"
echo "   Include transcript: $INCLUDE_TRANSCRIPT"
echo "   Include summary: $INCLUDE_SUMMARY"
echo "   Include action items: $INCLUDE_ACTION_ITEMS"
echo ""

# Register webhook
RESPONSE=$(curl -s -X POST "https://api.fathom.ai/external/v1/webhooks" \
    -H "X-[REDACTED_SECRET]" \
    -H "Content-Type: application/json" \
    -d "{
        \"destination_url\": \"$WEBHOOK_URL\",
        \"include_transcript\": $INCLUDE_TRANSCRIPT,
        \"include_summary\": $INCLUDE_SUMMARY,
        \"include_action_items\": $INCLUDE_ACTION_ITEMS,
        \"triggered_for\": [\"my_recordings\", \"shared_external_recordings\", \"my_shared_with_team_recordings\", \"shared_team_recordings\"]
    }")

# Check response
if echo "$RESPONSE" | jq -e '.id' >/dev/null 2>&1; then
    WEBHOOK_ID=$(echo "$RESPONSE" | jq -r '.id')
    WEBHOOK_SECRET=$(echo "$RESPONSE" | jq -r '.secret')
    
    echo "✅ Webhook registered!"
    echo ""
    echo "Webhook ID: $WEBHOOK_ID"
    echo "[REDACTED_SECRET]"
    echo ""
    echo "Save these! The secret is used to verify webhook signatures."
    echo ""
    echo "To delete this webhook later:"
    echo "  curl -X DELETE -H \"X-[REDACTED_SECRET]" \\"
    echo "    \"https://api.fathom.ai/external/v1/webhooks/$WEBHOOK_ID\""
else
    echo "❌ Failed to register webhook"
    echo "$RESPONSE" | jq -r '.error // .' 2>/dev/null || echo "$RESPONSE"
    exit 1
fi


path: scripts/setup.sh
content: #!/bin/bash
# Fathom API Setup - Validate and test connection

set -e

# Get API key
get_api_key() {
    if [ -n "$FATHOM_API_KEY" ]; then
        echo "$FATHOM_API_KEY"
    elif [ -f ~/.fathom_api_key ]; then
        cat ~/.fathom_api_key
    else
        echo ""
    fi
}

[REDACTED_SECRET])

if [ -z "$API_KEY" ]; then
    echo "❌ No API key found!"
    echo ""
    echo "Setup instructions:"
    echo "  1. Get your API key from https://developers.fathom.ai"
    echo "  2. Save it:"
    echo "     echo 'YOUR_KEY' > ~/.fathom_api_key"
    echo "     chmod 600 ~/.fathom_api_key"
    echo ""
    echo "  Or set environment variable:"
    echo "     export FATHOM_API_KEY='YOUR_KEY'"
    exit 1
fi

echo "🔑 API key found"
echo "🔗 Testing connection..."

RESPONSE=$(curl -s -w "\n%{http_code}" \
    -H "X-[REDACTED_SECRET]" \
    "https://api.fathom.ai/external/v1/meetings?limit=1")

HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | sed '$d')

if [ "$HTTP_CODE" = "200" ]; then
    echo "✅ Connection successful!"
    
    # Show account info
    CALL_COUNT=$(echo "$BODY" | jq -r '.items | length')
    if [ "$CALL_COUNT" -gt 0 ]; then
        LATEST=$(echo "$BODY" | jq -r '.items[0].title')
        echo "📞 Latest call: $LATEST"
    fi
    echo ""
    echo "You're all set! Try:"
    echo "  ./scripts/list-calls.sh"
elif [ "$HTTP_CODE" = "401" ]; then
    echo "❌ Invalid API key"
    echo "Check your key at https://developers.fathom.ai"
    exit 1
else
    echo "❌ Connection failed (HTTP $HTTP_CODE)"
    echo "$BODY" | jq -r '.error // .message // .' 2>/dev/null || echo "$BODY"
    exit 1
fi


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)