patreon-scraper-api
v0.0.1
Published
Patreon scraper API client: public creator pages, tier prices, about text and structured profile data via ScrapingBee.
Maintainers
Readme
patreon-scraper-api
Public Patreon creator data for Node, organised by what you are trying to find out.
npm install patreon-scraper-apiNode 16 or newer. One dependency, axios.
const { PatreonScraper } = require('patreon-scraper-api');
const bee = new PatreonScraper(process.env.SCRAPINGBEE_API_KEY);Key with 1,000 free credits: scrapingbee.com. Auth is a header, handled for you.
Run against patreon.com/kurzgesagt on 2026-09-10. Values below are recorded output.
First, what you cannot get
Worth settling before you build. Patron identities, member lists, individual pledge amounts, patron only posts and attachments all sit behind a login. Scraping under login credentials is prohibited by ScrapingBee's terms of service, so no option on this client reaches them and none of the examples pretend to.
Everything below reads what Patreon shows an anonymous visitor.
"I need a creator's name and what they make"
Cheapest and sturdiest. 5 credits.
const c = await bee.creator('kurzgesagt');
c.creator; // 'Kurzgesagt – In a Nutshell'
c.campaign_tagline; // 'Creating Science Animation Videos'
c.og_desc; // the short description Patreon shows to search enginescampaign_tagline is computed, not scraped. Patreon glues the creator name and the tagline together in the page title with an em dash, and a creator name can itself contain an en dash, so the split is safe. The client does it.
This route reads OpenGraph and title tags, which exist so share links render. They are the last thing on a Patreon page that will move.
"I need the whole about text, for search or embeddings"
5 credits, same page, richer output.
const p = await bee.profile('kurzgesagt');
p.name; // 'Kurzgesagt – In a Nutshell'
p.about; // 4,476 characters on the live page
p.image; // full size avatar
p.thumbnail; // 360px versioncreator() gives you roughly 160 characters of description. profile() gives 4,476, because it reads the ProfilePage object out of the page's structured data rather than the truncated meta tag.
One thing to know if you build this yourself: the extraction rule engine cannot read script tag contents. Selecting script[type="application/ld+json"] returns null, tested directly. So this fetches the page and parses the block. It also matches on @type rather than block index, because the live page carried six blocks and one of them describes Patreon the company rather than the creator.
"I need every tier and what it costs"
5 credits.
const ladder = await bee.priceLadder('kurzgesagt');[{ title: 'Free', price: 0, currency: 'USD', free: true, posts: 8 },
{ title: 'Trainee Producer', price: 3.14, currency: 'USD', free: false, posts: 1 },
{ title: 'Producer', price: 15, currency: 'USD', free: false, posts: 62 },
{ title: 'Senior Producer', price: 42, currency: 'USD', free: false, posts: 58 }]For the raw objects, with every field Patreon ships:
const t = await bee.tiers('kurzgesagt');
t.matched; // true
t.count; // 4
t.tiers[1]; // { title, amount_cents, currency, description, url, image_url,
// is_free_tier, post_count, published, requires_shipping,
// declined_patron_count, patron_amount_cents, patron_currency,
// discord_role_ids, remaining, user_limit }Do not read declined_patron_count as a patron count. It counts declined payments. Across those four tiers it reads 2, 31, 14 and 0, which is not a membership figure for a channel that size. Patreon publishes no per tier patron count on the public page, and this client keeps the field under its real name instead of dressing it up.
Trust amount_cents with currency. patron_amount_cents and patron_currency are also present, reading 800 and DKK on the free tier, which is not the tier price, so they come back untouched and uninterpreted.
remaining and user_limit were both null here. They hold real numbers on creators who cap a tier.
This route parses Patreon's own bootstrap payload, which is a private format with no stability guarantee. When it stops matching you get { tiers: [], matched: false, fallback }, where fallback is the creator() result. Check matched rather than treating an empty array as a creator with no tiers.
"I only need the entry price and I do not want a parser"
30 credits. Premium proxy plus JavaScript at 25, plus 5 for the AI query.
const e = await bee.entryPrice('kurzgesagt');
e.membership_tiers; // ['Access exclusive benefits starting at $3.14/month']
e.creator_name; // correct
e.about; // completemembership_tiers comes back as one teaser string, not an array of tiers. The tier cards are mounted by a component that has not rendered when the page is captured, so the model reported what was actually visible. That is the honest output.
Note the $3.14 matches amount_cents: 314 from tiers(), so both routes agree on the entry price by two independent paths.
If you want just that number without the AI call:
const entry = await bee.entryTier('kurzgesagt');
entry.title; // 'Trainee Producer'
entry.amount_cents; // 314entryTier() skips the free tier, since a price of zero is not an entry price. It costs 5 credits, not 30.
"I need to know what this is costing"
await bee.creator('kurzgesagt');
bee.lastCost; // 5
const acct = await bee.usage(); // free| Configuration | Credits | |---|---| | Auto mode on a creator page | 5 | | Premium proxy plus JavaScript | 25 | | The same plus an AI query | 30 | | Validation error | 0 |
Auto mode walks the proxy ladder cheapest first and bills only the rung that worked, and nothing at all when every rung fails. On Patreon that landed on the JavaScript rung. It cannot be combined with render_js, premium_proxy or stealth_proxy, and sending both returns HTTP 400 with nothing billed, which is easy to miss if you are not checking status codes.
At 5 credits a creator, 250,000 credits is 50,000 checks. Plan tiers.
Which route for which field
| Field | Route | Credits |
|---|---|---|
| Name, tagline | creator | 5 |
| Full about copy, avatar | profile | 5 |
| Every tier, price, post count | tiers / priceLadder | 5 |
| Cheapest paid tier | entryTier | 5 |
| Entry price teaser, no parser | entryPrice | 30 |
creator() and profile() read the same page, so if you want both, fetch once and run both parsers locally for one charge.
Elsewhere
Other creator platform pages: Substack scraper API, Twitch API, Snapchat scraper API, TikTok follower API, TikTok search API, YouTube shorts API, YouTube comment scraper API, YouTube transcript scraper API.
Features: AI web scraping, data extraction, markdown scraper, screenshots.
Route by route walkthrough with the raw payload shapes: github.com/ScrapingBee/patreon-api.
License
MIT
