Skip to the content.

TL;DR. Skool has no public API, so reading/writing data programmatically requires going through Skool’s internal endpoints — which are protected by cookies + AWS WAF + a buildId that rotates weekly. Building a maintainable Skool scraper is a ~50-hour engineering project that breaks weekly. The legitimate alternative is the Apify-hosted Skool All-in-One API actor — same data, structured response, ~$1.50/mo, maintained.

What people mean by “Skool scraper”

There are three different things people search “skool scraper” for:

  1. Export their own community’s data — own admin access, want a backup or to migrate. See Export Skool members to CSV / Sheets / CRM.
  2. Automate their own community — own admin access, want to post / approve programmatically
  3. Scrape someone else’s community — no admin access, want public data or scraping past member lists

This page covers (1) and (2). For (3) — that’s not what the actor does, and we don’t recommend it (legal, ethical, and reliability issues).

Why a hand-rolled scraper is harder than it looks

If you curl https://www.skool.com/your-community you get back HTML wrapped around an __NEXT_DATA__ script tag containing some of the data — but only the public view, no admin actions, no real-time data, no API calls.

The internal API at api.skool.com is what the Skool web app and mobile apps call. To reach it:

1. Authentication via Playwright

There’s no Authorization: Bearer header. Skool uses cookies issued after a real browser login flow. You have to drive a headless Chromium through the login screen, capture the resulting cookies, store them.

# Hand-rolled login (rough sketch — production needs much more)
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page()
    page.goto("https://www.skool.com/login")
    page.fill("input[name=email]", "...")
    page.fill("input[name=password]", "...")
    page.click("button[type=submit]")
    page.wait_for_url("https://www.skool.com/**")
    cookies = page.context.cookies()
    browser.close()

You now have auth_token, client_id, and several other cookies. But that’s not enough.

2. AWS WAF token rotation

Skool sits behind AWS WAF. Every request must include a fresh aws-waf-token. The token has a ~3.5-day TTL but the WAF can invalidate sooner under load patterns it considers suspicious. When invalid, you get a 403 with a JavaScript challenge embedded — Playwright can solve it, raw requests cannot. So your scraper needs a fallback Playwright session for token refresh.

3. buildId discovery

Skool’s Next.js app embeds a buildId in its HTML (<script id="__NEXT_DATA__">{"buildId":"abc123",...}</script>). API responses are sometimes shape-different across builds. You have to parse buildId from each page load and key your response parsers off of it.

When Skool deploys (~weekly), buildId changes, sometimes with breaking schema changes. Your scraper must detect this and adapt.

4. Endpoint coverage

Skool’s web app makes ~30 distinct endpoint calls across its surface. Each has:

Reverse engineering them all takes 30-50 hours of focused work. Maintaining them takes ~2 hours per week as Skool ships.

5. Rate limiting

Skool’s hard limit on writes is ~25/min. Hit it and you get 429s for ~5 minutes. Your scraper needs a queue. Implementing this correctly (with backoff, deduplication, idempotent retries for safe operations) is another ~10 hours.

6. Error structure

Skool’s internal error responses are inconsistent across endpoints. Some return {error: "..."}, some {message: "..."}, some return 200 with {success: false} in the body, some 4xx with HTML. Your scraper needs a normalizer.

The cost of “I’ll just build my own”

I built one. Then I rebuilt it as the Apify-hosted Skool API actor. Approximate development time:

Per-week maintenance: 1-3 hours when Skool ships. Past 12 months: ~80 hours of post-launch maintenance.

That’s all sunk cost so you don’t have to.

What the actor does that your scraper would have to

Component Your scraper Actor
Playwright login Build, host, maintain Chromium One JSON POST, ~10s
WAF token refresh Detect 403 + run Playwright fallback Automatic, transparent
buildId rotation Parse HTML weekly, adapt parsers Automatic
Endpoint coverage Reverse engineer ~25 endpoints All wrapped
Error structure Normalize 5+ different shapes {success, errorCode, hint, retryable}
Rate limit queue Build + test Built-in
TipTap conversion Build markdown→TipTap parser Built-in (classroom:setBody)
File uploads Multi-step signed URL flow One files:uploadImage call
Production deployment Your infra Apify-hosted
Monitoring Your dashboards Apify run logs
Per-week maintenance 1-3 hours 0 hours

When building your own would make sense

For 99% of Skool automation use cases (own community admin operations), the actor is the better choice.

What about RapidAPI / other “Skool API” listings?

There are a few Skool API marketplaces (RapidAPI, others) that list scrapers. We’ve evaluated them:

If you find one that works for your specific use case, great. For the full surface (read AND write across posts/members/classroom/files), the actor is currently the only complete option.


Skip the build, use the actor

→ Open the Skool All-in-One API actor on Apify

Read AND write across the full Skool admin surface. One POST per action. Pay-per-event (~$1.50/mo typical). 80+ hours of maintenance done for you.

No Skool community yet? Launch one in 10 minutes — 14-day free trial.