Skip to main content

patreon-scraper-api

A Python client for scraping public Patreon creator pages through ScrapingBee. Four extraction routes, each with a documented cost and a documented failure mode.

Verified against https://www.patreon.com/kurzgesagt on 2026-09-10. Every field name, credit figure and return value below came from a real call. Two of the four routes have caveats that only a live run exposes, and both are written down rather than smoothed over.

pip install patreon-scraper-api

Requires Python 3.8 or newer and requests.

What is in scope

Public creator pages, read anonymously.

Reachable: creator display name, campaign tagline, the full about text, avatar and banner URLs, canonical URL, the complete tier list with prices and per tier post counts, and the entry price teaser.

Not reachable, by design: patron only posts, attachment downloads, member lists, individual pledge amounts and direct messages. Those require a signed in session, and scraping under login credentials is prohibited by ScrapingBee's terms of service. No parameter in this package changes that.

Authentication

from patreon_scraper_api import PatreonScraper

bee = PatreonScraper("YOUR_API_KEY")

Sent as Authorization: Bearer YOUR_API_KEY on every request. The api_key query parameter still answers but the current documentation marks it deprecated.

Key and 1,000 free credits: ScrapingBee. Landing page for this target: Patreon scraper API.


Method reference

creator(slug)

5 credits. Meta tags, via extract_rules. The route that does not break, because these tags exist for social preview cards rather than for the application.

bee.creator("kurzgesagt")
{
 'creator': 'Kurzgesagt – In a Nutshell',
 'title': 'Kurzgesagt – In a Nutshell — Creating Science Animation Videos | Patreon',
 'og_title': 'Kurzgesagt – In a Nutshell — Creating Science Animation Videos',
 'og_desc': 'Get more from Kurzgesagt – In a Nutshell on Patreon. Creating Science '
            'Animation Videos. Support Kurzgesagt – In a Nutshell and get exclusive '
            'access to their work.',
 'campaign_tagline': 'Creating Science Animation Videos',
}

campaign_tagline is derived, not scraped. Patreon joins the creator name and the tagline with an em dash, while a creator name may itself contain an en dash, so splitting on the em dash is unambiguous. The client does that split for you.

mode=auto walks the proxy ladder and bills only the rung that worked, which was the JavaScript rung at 5 credits. spb-initial-status-code reported 308, which is Patreon's canonical redirect rather than a block.

profile(slug)

5 credits. The application/ld+json ProfilePage block, parsed after the fetch.

bee.profile("kurzgesagt")
# {'name': 'Kurzgesagt – In a Nutshell',
#  'alternate_name': 'Kurzgesagt',
#  'url': 'https://www.patreon.com/Kurzgesagt',
#  'about': '<4,476 characters>',
#  'image': 'https://c10.patreonusercontent.com/...',
#  'thumbnail': 'https://c10.patreonusercontent.com/...'}

Use this over creator() when you need the complete about copy, for search indexing or embeddings. The meta description truncates it. The live page carried 4,476 characters here against roughly 160 in og_desc.

Why this parses HTML instead of using extract_rules: because extract_rules cannot reach script tag contents. A rule of {"jsonld": {"selector": "script[type=\"application/ld+json\"]", "output": "@text"}} returns None. That was tested directly, not assumed. The client fetches the page and parses the block itself.

The live page carried six such blocks, and their order is not stable, so the client matches on @type. One of them is an Organization block describing Patreon rather than the creator, which is exactly the row an index based parser would pick up by mistake.

tiers(slug)

5 credits. The complete tier list, from Patreon's own bootstrap payload.

result = bee.tiers("kurzgesagt")
result["matched"]  # True
result["count"]    # 4

Live output, sorted cheapest first:

title amount_cents is_free_tier post_count declined_patron_count
Free 0 True 8 2
Trainee Producer 314 False 1 31
Producer 1500 False 62 14
Senior Producer 4200 False 58 0

Every key on a tier object: 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.

declined_patron_count is not a patron count. It counts declined payments. It reads 2, 31, 14 and 0 across those tiers, which is nothing like a membership figure for a creator of that size. Patreon does not publish a per tier patron count on the public page, so this package passes the field through under its real name rather than relabelling it as something more useful.

amount_cents with currency is the tier price and is the pair to trust. patron_amount_cents and patron_currency also appear, reading 800 and DKK on the free tier, which does not correspond to the tier price, so they are returned raw without interpretation.

remaining and user_limit were both None on every tier here. They carry real values on creators who cap a tier.

This route reads a private application format Patreon has no obligation to keep stable. When the pattern stops matching, the client returns {"tiers": [], "matched": False, "fallback": <creator() result>} rather than an empty list that reads like a creator with no tiers.

price_ladder(slug) and entry_tier(slug)

Convenience wrappers over tiers(), same 5 credits.

bee.price_ladder("kurzgesagt")
# [{'title': 'Free',             'price': 0.0,  'currency': 'USD', 'free': True,  'posts': 8},
#  {'title': 'Trainee Producer', 'price': 3.14, 'currency': 'USD', 'free': False, 'posts': 1},
#  {'title': 'Producer',         'price': 15.0, 'currency': 'USD', 'free': False, 'posts': 62},
#  {'title': 'Senior Producer',  'price': 42.0, 'currency': 'USD', 'free': False, 'posts': 58}]

bee.entry_tier("kurzgesagt")["title"]  # 'Trainee Producer'

entry_tier() skips the free tier, because amount_cents of 0 is not an entry price.

entry_price(slug)

30 credits. Premium proxy plus JavaScript at 25, plus 5 for the AI query. Uses ai_extract_rules, so there is no parser to maintain.

bee.entry_price("kurzgesagt")
# {'creator_name': 'Kurzgesagt – In a Nutshell',
#  'about': '<full about text>',
#  'membership_tiers': ['Access exclusive benefits starting at $3.14/month']}

creator_name and about come back complete and correct. membership_tiers comes back as a single teaser string, not a tier array, because the tier cards are mounted by a component that has not rendered at capture time. The model described what was actually on the page, which is the honest result rather than a broken one.

That said, $3.14 matches the amount_cents value of 314 that tiers() reads out of the payload, so the two routes independently agree on the entry price. Use entry_price() when you want that one number and no parser. Use tiers() when you want the whole ladder.

usage()

Free. Account credits, concurrency and renewal date.


Choosing a route

You need Method Credits
Name and tagline for a directory creator 5
Full about copy for search or embeddings profile 5
Every tier with its price and post count tiers 5
A price ladder ready to display price_ladder 5
Entry price only, no parser to own entry_price 30

creator() and profile() read the same fetched page, so if you want both, fetch raw once and run both parsers locally for a single 5 credit charge.

Credit cost

Measured from spb-cost headers. Available on bee.last_cost after every call.

Configuration Credits
mode=auto on a creator page, settled at the JavaScript rung 5
render_js plus premium_proxy 25
The same plus ai_extract_rules 30
Validation error 0

Auto mode is the right default here: it charges only for the configuration that worked, and nothing at all if every rung fails. It is incompatible with render_js, premium_proxy and stealth_proxy, and sending both returns HTTP 400 while billing nothing, which fails quietly if you do not read status codes.

At 5 credits per creator, 250,000 credits covers 50,000 creator checks. Plan tiers: ScrapingBee pricing.

Related

Landing pages for adjacent creator platforms: Substack scraper API, Twitch API, TikTok API, TikTok follower API, YouTube video scraper API, YouTube transcript scraper API, YouTube comment scraper API, Snapchat scraper API.

Features: AI web scraping, data extraction, markdown scraper, screenshots, JavaScript scenario, n8n integration.

Reference: extraction rules documentation. Guide version with the full route walkthrough: github.com/ScrapingBee/patreon-api.

License

MIT

Release files for patreon-scraper-api 0.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for patreon-scraper-api 0.0.1
File Size Uploaded
patreon_scraper_api-0.0.1.tar.gz 13.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for patreon-scraper-api 0.0.1
File Interpreter ABI Platform
patreon_scraper_api-0.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 23.7 kB

Release files / patreon_scraper_api-0.0.1.tar.gz

Download URL patreon_scraper_api-0.0.1.tar.gz
Size 13.1 kB
Tags Source
SHA-256 checksum
How to use checksums
2f47809c5f9ad4b2a742b3e8f2de717083e263b0525bc1eef04180fcf5c4f6d6
BLAKE2b-256 checksum
How to use checksums
9aa3732d25d12781e2f39154ce7aa9e512e529f5a89cfbd475364a6ee6ca968c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Release files / patreon_scraper_api-0.0.1-py3-none-any.whl

Download URL patreon_scraper_api-0.0.1-py3-none-any.whl
Size 10.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ae4e394cf7f9934adc72ed8e03155b6446d6c308b43c4885329dbb69fac08cd4
BLAKE2b-256 checksum
How to use checksums
ffec35294dcb34716e81924aa7063aa8640ea6de3969f4ecf5f365c0672b667d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Release history Release notifications | RSS feed

This release

0.0.1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page