Skip to the content.

Community analytics: export Skool data to NocoDB / Airtable

Use case: Skool’s built-in analytics are minimal. You want your own BI dashboard tracking members over time, engagement by category, churn signals, and free → paid conversion. This recipe shows the pattern: scheduled actor runs that export Skool data to your own database (NocoDB, Airtable, Postgres, or anywhere) for analysis.

The stack we use in production: Skool actor → n8n cron → NocoDB tables → Metabase / Grafana for dashboards. But the pattern works with any tools.

What you’ll track

Table What it captures Update frequency
members_snapshots Full member list each week with role, level, joined_at, last_active_at Weekly
posts_engagement Each post with author, category, comments, likes, created_at Daily incremental
member_activity Per-member metric: posts_count, comments_count, last_post_at Daily
cohorts New members grouped by join week, tracked for activation + retention Weekly
revenue_signals Members who upgraded tier, when, and what they posted before upgrading On-demand

The recipe

Step 1 — Schema in NocoDB (or your DB of choice)

Create a NocoDB base with these tables:

members_snapshots
├── id (autonumber, PK)
├── snapshot_date (date)
├── skool_user_id (text)
├── first_name (text)
├── last_name (text)
├── username (text)
├── joined_at (datetime)
├── role (text) — member / admin / banned
├── tier (number) — 0 free, 2 premium, 3 vip
├── level (number)
├── linkedin_url (text)
└── why_join (text)

posts_engagement
├── id (autonumber, PK)
├── post_id (text, unique)
├── author_id (text)
├── author_name (text)
├── category_id (text)
├── title (text)
├── content_preview (text — first 500 chars)
├── comment_count (number)
├── like_count (number)
├── pinned (bool)
├── created_at (datetime)
└── last_synced (datetime)

member_activity
├── id (autonumber, PK)
├── skool_user_id (text)
├── period_start (date) — Monday of the week
├── posts_count (number)
├── comments_count (number)
├── likes_received (number)
└── last_post_at (datetime)

Step 2 — n8n workflow: weekly member snapshot

Trigger: Cron every Monday at 9am.

Nodes:

  1. HTTP Requestauth:login if cookies expired, otherwise skip
  2. HTTP Requestmembers:list (paginated, iterate until empty)
  3. Code node — flatten members array, add snapshot_date = today
  4. NocoDB Insert Bulk — upsert into members_snapshots
  5. Code node — compute deltas vs last snapshot:
    • New joiners: in this snapshot, not in last
    • Churners: in last snapshot, not in this
    • Upgrades: tier increased
    • Downgrades: tier decreased
  6. Telegram notification — summary delta to your ops channel

Example actor call:

curl -X POST "https://api.apify.com/v2/acts/cristiantala~skool-all-in-one-api/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "action": "members:list",
    "groupSlug": "my-community",
    "cookies": "auth_token=...; ...",
    "params": {
      "page": 1
    }
  }'

Step 3 — n8n workflow: daily post engagement sync

Trigger: Cron every day at 3am (low-traffic window).

Nodes:

  1. HTTP Requestposts:list (pages 1-3, covers last ~96 posts which is typically all activity in 24h)
  2. Code node — for each post, compute last_synced = now
  3. NocoDB Upsert by post_id — insert new posts, update existing ones with new comment_count/like_count
  4. Code node — flag posts where comment_count grew >5 since last sync (potential viral)
  5. Telegram notification if any viral post detected

This pattern catches posts that gain traction overnight so you can engage early in the morning.

Step 4 — Compute member_activity weekly

Once posts_engagement is populated daily, compute weekly per-member rollups:

-- Run as scheduled SQL in NocoDB or via your DB tool
INSERT INTO member_activity (skool_user_id, period_start, posts_count, comments_count, last_post_at)
SELECT
  author_id,
  DATE_TRUNC('week', NOW()) AS period_start,
  COUNT(*) FILTER (WHERE parent_id IS NULL) AS posts_count,
  COUNT(*) FILTER (WHERE parent_id IS NOT NULL) AS comments_count,
  MAX(created_at) AS last_post_at
FROM posts_engagement
WHERE created_at >= DATE_TRUNC('week', NOW())
GROUP BY author_id;

(Adapt to your DB’s syntax. NocoDB supports SQL views over its tables.)

Step 5 — Build dashboards

Now you have time-series data. Useful queries:

Weekly active members (WAU):

COUNT(DISTINCT skool_user_id) FROM member_activity
WHERE period_start = DATE_TRUNC('week', NOW())
AND (posts_count > 0 OR comments_count > 0)

Activation rate (% of new joiners that post within 14 days):

SELECT
  DATE_TRUNC('week', joined_at) AS cohort_week,
  COUNT(*) AS joined,
  COUNT(*) FILTER (WHERE first_post_at <= joined_at + INTERVAL '14 days') AS activated,
  COUNT(*) FILTER (WHERE first_post_at <= joined_at + INTERVAL '14 days') * 100.0 / COUNT(*) AS activation_pct
FROM members_with_first_post
GROUP BY cohort_week
ORDER BY cohort_week DESC;

Churn signal (paid members who stopped posting):

SELECT first_name, last_name, username, tier, last_post_at
FROM members_snapshots
WHERE snapshot_date = (SELECT MAX(snapshot_date) FROM members_snapshots)
  AND tier > 0
  AND last_post_at < NOW() - INTERVAL '30 days'
ORDER BY tier DESC, last_post_at ASC;

These are the members worth a personal DM before they churn.

Pricing estimate

For a community with 500 members and ~30 new posts/day:

Workflow Frequency Skool calls Cost/run Monthly cost
Weekly member snapshot Weekly ~20 (paginated 500 members) ~$0.11 ~$0.50
Daily post sync Daily ~5 (3 pages of 32 posts) ~$0.02 ~$0.60
auth:login refresh Every 3 days 1 ~$0.02 ~$0.20
Total       ~$1.30/month

For a 5,000-member community: ~$10-15/month. Still trivial vs subscription analytics SaaS at $50-200/month.

What you can do with this data

Caveats