How to build Patreon membership dashboards in Metabase
Patreon is a membership platform where creators earn recurring income from patrons across pledge tiers — with an API whose member objects are shaped almost exactly like subscription analytics. Metabase is where you turn that data into shared, trustworthy dashboards. This guide covers two complementary paths: a lightweight API + CLI route that pulls live data via the Patreon Members API and loads a CSV into Metabase with the Metabase CLI, and a durable pipeline route that lands Patreon data in a database so you can build dashboards anyone can read.
How do you connect Patreon to Metabase?
Most teams combine both routes: quick answers through API exports and CLI uploads first, then recurring reporting on a warehouse-backed model.
The single most important detail on this page: Patreon's API returns almost nothing unless you explicitly request each attribute with fields[member]=…. Omit it and you get member objects with IDs and little else — which looks like an empty account rather than a malformed request, and costs people hours.
Live answers in, quick analysis out
Script a scoped export against the Patreon Members API, write the result to CSV, then load it into Metabase as a ready-to-query table and model.
- Quick questions such as "show me active patrons and net member change"
- Loading Patreon exports into Metabase in seconds
- Spot-checks and one-off investigations without pipeline work
- Great for exploration, not month-end reporting anyone signs off on
- Use read-only credentials or scoped tokens wherever supported
- CSV uploads are snapshots — refresh or move to the pipeline for history
Durable dashboards with history
Land Patreon data in a database or warehouse — via connector, scheduled API pulls, or a direct database connection — then point Metabase at it.
- Patreon dashboards the whole team reads from the same definitions
- Joining this data with orders, customers, and revenue from the rest of the stack
- Long-run trends for active patrons and net member change and monthly membership revenue by tier
- You own the refresh schedule and the rollup grain
- Model gross, fee, and net amounts once, in the warehouse layer
- Late-arriving records restate recent periods — plan for it
What can you analyze from Patreon data in Metabase?
Each of these is built from members joined to the related campaigns and patron counts, pledge tiers and entitled amounts, charge dates and payment status data your export exposes:
- Active patrons and net member change
- Monthly membership revenue by tier
- Churn by tenure cohort
- Failed payments and declined patrons
- Lifetime support distribution
Which Patreon dashboards should you build in Metabase?
Membership base
How the member count is moving.
- Active members (number + trend)
- New vs. churned members by month (stacked bar)
- Net member change (waterfall or bar)
- Members by tier (bar)
Recurring revenue
What membership is worth per month.
- Monthly membership revenue (line)
- Average revenue per member (line)
- Revenue by tier and its mix over time (stacked area)
- Upgrades vs. downgrades between tiers (bar)
Churn
Who leaves, and when.
- Monthly member churn rate (line)
- Churn by tenure cohort (heat table)
- Survival curve by join cohort (line)
- Failed payments preceding churn (table)
Take-home and lifetime value
Net earnings and what a member is worth.
- Net earnings after platform and processing fees (combo)
- Effective fee rate by month (line)
- Median lifetime support per member (number)
- Lifetime value by tier (bar)
How do you use the Patreon Members API with the Metabase CLI?
Pair the Patreon Members API with the Metabase CLI for fast, hands-on analysis. A short scripted export covers the pulls an MCP server would otherwise make; the Metabase CLI's upload command loads CSV data into Metabase and creates a ready-to-query table and model.
Example workflow
- Ask the API for the current members with tier, patron status, pledge amount, and lifetime support.
- Export the result as CSV, keeping stable IDs, dates, currency codes, and the fee breakdown intact.
- Run
mb upload csvto load it into Metabase as a table and model, then build questions and dashboards on top.
Be honest about the limits
- Scripted API pulls are excellent for exploration, not scheduled reporting.
- A CSV upload is a snapshot; refresh it with
mb upload replaceor move to the pipeline for real history. - Member counts are point-in-time snapshots. Churn and net-member-change trends only work once you capture a snapshot per day or per month and append it.
mb upload csvneeds an uploads database configured under Admin → Settings → Uploads.
How do you set up the Patreon API and the Metabase CLI?
Patreon Members APIno vendor MCP
- Transport
- REST over HTTPS (patreon.com/api/oauth2/v2)
- Auth
- Bearer token (OAuth or a creator access token)
- Best for
- Scheduled daily member snapshots
Metabase CLIofficial
- Install
npm install -g @metabase/cli- Auth
mb auth login- Load data
mb upload csv --file data.csv- Requires
- An uploads database (Admin → Settings → Uploads)
# CRITICAL: every attribute must be named in fields[...] or the
# response comes back nearly empty — the classic silent-empty bug.
BASE=https://www.patreon.com/api/oauth2/v2
FIELDS='fields[member]=patron_status,currently_entitled_amount_cents,\
lifetime_support_cents,campaign_lifetime_support_cents,will_pay_amount_cents,\
pledge_cadence,pledge_relationship_start,last_charge_date,last_charge_status,\
next_charge_date,is_free_trial,is_gifted,is_follower,full_name'
curl -s -G "${BASE}/campaigns/${CAMPAIGN_ID}/members" \
-H "Authorization: Bearer $PATREON_TOKEN" \
--data-urlencode "$FIELDS" \
--data-urlencode 'page[count]=500' \
> patreon-members.json
# Stamp today's date so daily snapshots build real churn history
jq -r --arg d "$(date -u +%F)" '.data[] | [
$d, .id, .attributes.patron_status,
(.attributes.currently_entitled_amount_cents / 100),
(.attributes.campaign_lifetime_support_cents / 100),
.attributes.pledge_cadence, .attributes.pledge_relationship_start,
.attributes.last_charge_date, .attributes.last_charge_status
] | @csv' patreon-members.json > patreon-creator-members.csvThere is no official Patreon MCP server (verified July 2026). The community options are thin — the most visible one is a small Python server with a handful of stars and no commits since March 2026 — and a Zapier bridge exists but adds a hop without adding data. The API is straightforward enough that scripting it directly is both simpler and more reliable. Note too that Patreon's v1 API is described by the vendor as unmaintained and deprecated soon; build on v2.
# Install the Metabase CLI
npm install -g @metabase/cli
# Log in (opens your browser; requires Metabase v62+)
mb auth login --url https://your-metabase.example.com
# Load a members export — creates a table AND a model
mb upload csv --file patreon-members.csv --collection root
# Refresh that same table later from a new export
mb upload replace <table-id> --file patreon-members.csvCan you generate a Patreon dashboard with AI?
Yes. Use the prompt below with any assistant that can run shell commands (for the API export) and the Metabase CLI. It works end to end: if Patreon tables already exist in Metabase it analyzes those; otherwise it pulls scoped, summarized data, loads it with mb upload csv, then builds the dashboard and caveats any metric that needs missing history.
Create a polished Metabase dashboard for Patreon membership analytics.
Work end to end: get the data into Metabase if it isn't there yet, then build.
Goal: Help the team understand active members, new vs. churned, revenue by tier, churn by cohort, and net earnings after fees from Patreon data.
Step 1 — Find or load the data:
- First, check what already exists in Metabase (search for patreon tables and
models). If durable Patreon data is already present — a warehouse sync, a
direct database connection, or an earlier upload — use it and skip to Step 2.
- If nothing is there, pull a scoped, summarized export by scripting the Patreon Members API:
members, plus campaigns and patron counts, pledge tiers and entitled amounts, charge dates and payment status.
Write each result to a CSV, then load it with the Metabase CLI — run
"mb upload csv --file <export>.csv" so each upload creates a table and a
ready-to-query model. Use "mb upload replace <table-id> --file <export>.csv"
to refresh an existing table instead of creating duplicates.
Step 2 — Inspect before querying:
Do not assume exact table or column names. Inspect available fields, products,
locations or countries, currencies, and date ranges before creating trend cards.
Important:
- Build on whatever data is present; don't claim Metabase connects natively to
Patreon — it reads a database or CLI-uploaded tables.
- Separate gross amounts, platform and processing fees, taxes, and refunds into
distinct columns; never let one card silently mix gross and net.
- A single CSV is a point-in-time snapshot: only build trend cards if there is
a usable date column or multiple periods have been uploaded.
- Member counts are point-in-time snapshots. Churn and net-member-change trends only work once you capture a snapshot per day or per month and append it.
- If a metric can't be computed from the data present, say so on the card
instead of approximating it.
Dashboard title: Patreon Membership Overview
Sections:
1. Executive summary: Active members; Net member change; Churn rate;
Monthly membership revenue; Average revenue per member.
2. Base: Active members trend; new vs. churned; members by tier.
3. Revenue: Membership revenue by month; revenue by tier; upgrades vs. downgrades.
4. Churn: Churn rate; churn by tenure cohort; survival by join cohort.
5. Earnings: Net after fees; effective fee rate; lifetime value by tier.
Filters: Date range, Tier, Patron status, Pledge cadence, Cohort.
Output: Build the dashboard if you have permission; otherwise provide the exact
questions, SQL, model definitions, and layout. Include caveats for any metric
that cannot be calculated from the available data.How do you sync Patreon data into a database or warehouse?
For dashboards that need history and reliability, land Patreon data in a database first, then connect Metabase to that database.
Connector options
- Managed connector — use Airbyte, Fivetran, or dlt when one genuinely covers the objects you need.
- Custom pipeline — use the Patreon Members API for control over grain, fields, and refresh cadence.
- API + CSV — use this for quick exploration and one-off slices.
No managed connector exists on Airbyte, Fivetran, or dlt (verified July 2026). The pattern that matters here is snapshotting: the Members endpoint returns current state, not history, so schedule a daily pull that appends every member row stamped with the snapshot date. Rate limits are 100 requests per 2 seconds at the client level and 100 per minute per token — generous for this job. Fetching patron emails needs the separate <code>campaigns.members[email]</code> scope.
Notes
- Decide the grain first (one row per member per daily snapshot — the only way to get real churn history) — it drives every trend card.
- Land raw tables first, then build clean Metabase models on top.
- Normalize snapshot-date, member-id, tier, patron-status, pledge-amount, and lifetime-support fields.
How should you model Patreon data in Metabase?
Core tables
| Table | Grain | Key columns |
|---|---|---|
creator_members | one row per member per daily snapshot | snapshot_date, member_id, patron_status, currently_entitled_amount_cents, campaign_lifetime_support_cents, pledge_cadence, pledge_relationship_start, last_charge_date, last_charge_status, next_charge_date, is_free_trial, is_gifted |
creator_products | one row per pledge tier | tier_id, campaign_id, title, amount_cents, published_at |
Modeling advice
- Build a clean
creator_membersmodel with the same column names you use for sibling tools, so cross-tool dashboards don't fork definitions. - Keep gross amount, platform fee, processing fee, tax, and net amount as separate, labeled columns — never let one card silently mix them.
patron_statustakes three values —active_patron,declined_patron,former_patron. A declined patron is a failed payment, not a churned one; counting them as churn overstates it and hides a recoverable dunning problem.- Use
campaign_lifetime_support_cents, notlifetime_support_cents, for per-campaign revenue — they are different fields, and the unscoped one spans every campaign the patron supports. pledge_cadenceis 1 for monthly and 12 for annual: normalize to a monthly figure before summing, or annual patrons will look twelve times more valuable than they are in any given month.- Store amounts in minor units or with an explicit currency column, and convert once in the model layer rather than per card.
Which Patreon metrics should you track in Metabase?
| Metric | Definition | Notes |
|---|---|---|
| MRR | Monthly recurring pledge revenue, cadence-normalized. | Annual pledges must be divided by 12, not counted whole. |
| Churn rate | Patrons lost over active patrons at period start. | Separate declined payments from genuine cancellations. |
| LTV | Lifetime support per patron, from campaign-scoped totals. | The median beats the mean — a few whales distort it. |
| ARPU | Average entitled amount per active patron. | Tier mix moves this more than price changes do. |
What SQL powers Patreon dashboards in Metabase?
These assume a cleaned analytical model in a warehouse (PostgreSQL dialect). Adjust table and column names to match your pipeline.
Monthly and annual pledges brought onto one comparable basis.
SELECT
snapshot_date,
COUNT(*) FILTER (WHERE patron_status = 'active_patron') AS active_patrons,
COUNT(*) FILTER (WHERE patron_status = 'declined_patron') AS declined,
ROUND(
SUM(
CASE
WHEN patron_status <> 'active_patron' THEN 0
-- cadence 12 means an annual pledge; spread it over the year.
WHEN pledge_cadence = 12
THEN currently_entitled_amount_cents / 12.0
ELSE currently_entitled_amount_cents
END
) / 100.0, 2
) AS mrr,
ROUND(
AVG(currently_entitled_amount_cents) FILTER (
WHERE patron_status = 'active_patron'
) / 100.0, 2
) AS arpu
FROM creator_members
GROUP BY snapshot_date
ORDER BY snapshot_date DESC;Genuine cancellations, with declined payments held out separately.
WITH month_end AS (
SELECT DISTINCT ON (date_trunc('month', snapshot_date))
date_trunc('month', snapshot_date)::date AS month,
snapshot_date
FROM creator_members
ORDER BY date_trunc('month', snapshot_date), snapshot_date DESC
), status_by_month AS (
SELECT m.month, c.member_id, c.patron_status
FROM month_end m
JOIN creator_members c ON c.snapshot_date = m.snapshot_date
)
SELECT
s.month,
COUNT(*) FILTER (WHERE p.patron_status = 'active_patron')
AS active_at_start,
COUNT(*) FILTER (
WHERE p.patron_status = 'active_patron'
AND s.patron_status = 'former_patron'
) AS churned,
ROUND(
100.0 * COUNT(*) FILTER (
WHERE p.patron_status = 'active_patron'
AND s.patron_status = 'former_patron'
) / NULLIF(COUNT(*) FILTER (
WHERE p.patron_status = 'active_patron'
), 0), 2
) AS churn_rate_pct
FROM status_by_month s
JOIN status_by_month p
ON p.member_id = s.member_id
AND p.month = s.month - INTERVAL '1 month'
GROUP BY s.month
ORDER BY s.month DESC;How long patrons stay, grouped by the month they first pledged.
WITH latest AS (
SELECT * FROM creator_members
WHERE snapshot_date = (SELECT MAX(snapshot_date) FROM creator_members)
)
SELECT
date_trunc('month', pledge_relationship_start)::date AS cohort_month,
COUNT(*) AS patrons_ever,
COUNT(*) FILTER (WHERE patron_status = 'active_patron') AS still_active,
ROUND(
100.0 * COUNT(*) FILTER (WHERE patron_status = 'active_patron')
/ NULLIF(COUNT(*), 0), 1
) AS retention_pct,
ROUND(
PERCENTILE_CONT(0.5) WITHIN GROUP (
ORDER BY campaign_lifetime_support_cents / 100.0
)::numeric, 2
) AS median_lifetime_support
FROM latest
GROUP BY cohort_month
ORDER BY cohort_month DESC;What are common mistakes when analyzing Patreon in Metabase?
Related
Related analytics
Related dashboards
Related integrations
FAQ
Does Metabase connect natively to Patreon?
Should Metabase replace Patreon's built-in reports?
Is there an official Patreon MCP server?
Why does my Patreon export come back empty?
fields[member]=patron_status,currently_entitled_amount_cents,…. Without it you get member IDs and nothing else — and the response is a valid 200, so nothing signals the mistake. Patron emails additionally need the campaigns.members[email] scope.