How to build Gumroad sales dashboards in Metabase
Gumroad is a checkout and storefront for independent creators selling digital products — ebooks, software, templates, memberships — with a free API that exposes every sale, fee, and subscriber. 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 Gumroad Sales API and loads a CSV into Metabase with the Metabase CLI, and a durable pipeline route that lands Gumroad data in a database so you can build dashboards anyone can read.
How do you connect Gumroad to Metabase?
Most teams combine both routes: quick answers through API exports and CLI uploads first, then recurring reporting on a warehouse-backed model.
Live answers in, quick analysis out
Script a scoped export against the Gumroad Sales 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 gross vs. net sales after gumroad fees"
- Loading Gumroad 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 Gumroad data in a database or warehouse — via connector, scheduled API pulls, or a direct database connection — then point Metabase at it.
- Gumroad 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 gross vs. net sales after gumroad fees and product and variant performance
- 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 Gumroad data in Metabase?
Each of these is built from sales joined to the related products and variants, subscribers and recurring charges, refunds, chargebacks, and disputes data your export exposes:
- Gross vs. net sales after Gumroad fees
- Product and variant performance
- Launch-week revenue by product
- Refund and chargeback rate
- Membership subscriber movement
Which Gumroad dashboards should you build in Metabase?
Sales
The headline revenue picture.
- Gross vs. net sales after fees (combo)
- Sales by product, top 10 (bar)
- Daily sales trend with launch spikes visible (line)
- Refund rate by product (bar)
Launch performance
How each drop actually did.
- Revenue in the first 7 days after launch by product (bar)
- Discount code usage and its revenue share (table)
- Average order value over time (line)
- Sales by referrer where the data exists (table)
Customers
Who buys, and who buys again.
- Repeat purchase rate (number + trend)
- Customers by number of purchases (histogram)
- Revenue from repeat vs. new customers (stacked bar)
- Top customers by lifetime spend (table)
Take-home
What lands after everyone takes a cut.
- Effective platform fee rate by month (line)
- Net revenue per product after fees (table)
- Refunds and chargebacks in dollars (bar)
- Payout timing vs. sale date (table)
How do you use the Gumroad Sales API with the Metabase CLI?
Pair the Gumroad Sales 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 last 90 days of sales, one row per sale with product, price, fees, and refund flag.
- 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. - Trends need complete months of sales history — a single export covers only the window you requested.
mb upload csvneeds an uploads database configured under Admin → Settings → Uploads.
How do you set up the Gumroad API and the Metabase CLI?
Gumroad Sales APIofficial API
- Transport
- REST over HTTPS (api.gumroad.com/v2)
- Auth
- OAuth access token with view_sales / view_payouts scopes
- Best for
- Scripted sales, subscriber, and payout exports
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)
# Generate an access token on your Gumroad application page.
# /sales pages with an opaque cursor (page_key), not numeric offsets.
BASE=https://api.gumroad.com/v2
NEXT="${BASE}/sales?access_token=${GUMROAD_TOKEN}&after=2026-01-01"
: > gumroad-sales.json
while [ -n "$NEXT" ]; do
RESP=$(curl -s "$NEXT")
echo "$RESP" | jq -c '.sales[]' >> gumroad-sales.json
NEXT=$(echo "$RESP" | jq -r '.next_page_url // empty')
[ -n "$NEXT" ] && NEXT="https://api.gumroad.com${NEXT}"
done
# Flatten to CSV for the Metabase CLI
jq -r '[
.id, .created_at, .product_name, .price, .gumroad_fee, .tax_cents,
.subscription_id, (.is_recurring_billing | tostring),
(.refunded | tostring), (.chargedback | tostring),
.variants, .utm_source, .utm_campaign
] | @csv' gumroad-sales.json > gumroad-creator-orders.csvGumroad publishes no official MCP server. A community one exists (gumroad-mcp on npm, from rmarescu/gumroad-mcp), but it has had no commit or release since April 2025 — fifteen months stale as of this writing — so treat it as unmaintained rather than as a recommendation. Gumroad's own agent-facing path is now its CLI (brew install antiwork/cli/gumroad), which the vendor describes as built for humans and AI agents alike; either it or the raw API beats a stale wrapper.
# 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 sales export — creates a table AND a model
mb upload csv --file gumroad-sales.csv --collection root
# Refresh that same table later from a new export
mb upload replace <table-id> --file gumroad-sales.csvCan you generate a Gumroad 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 Gumroad 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 Gumroad digital product sales analytics.
Work end to end: get the data into Metabase if it isn't there yet, then build.
Goal: Help the team understand gross vs. net sales, product and launch performance, repeat purchase, and effective fee rate from Gumroad data.
Step 1 — Find or load the data:
- First, check what already exists in Metabase (search for gumroad tables and
models). If durable Gumroad 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 Gumroad Sales API:
sales, plus products and variants, subscribers and recurring charges, refunds, chargebacks, and disputes.
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
Gumroad — 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.
- Trends need complete months of sales history — a single export covers only the window you requested.
- If a metric can't be computed from the data present, say so on the card
instead of approximating it.
Dashboard title: Gumroad Digital Product Sales Overview
Sections:
1. Executive summary: Net sales this month; MoM growth; Refund rate;
Effective fee rate; Repeat purchase rate.
2. Sales: Gross vs. net by month; sales by product; daily trend.
3. Launches: First-7-day revenue by product; discount usage; AOV over time.
4. Customers: Repeat purchase rate; purchases per customer; top customers.
5. Take-home: Fee rate by month; net per product; refunds in dollars.
Filters: Date range, Product, Variant, UTM source or campaign, Currency.
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 Gumroad data into a database or warehouse?
For dashboards that need history and reliability, land Gumroad 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 Gumroad Sales 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). Schedule your own <code>/sales</code> pull — note that it pages with an opaque <code>page_key</code> cursor rather than numeric offsets, so follow <code>next_page_url</code> rather than incrementing a counter. Gumroad doesn't publish rate limits, so be conservative. The <code>/earnings</code> endpoint is limited to US sellers with the Tax Center enabled; derive earnings from sales and fees otherwise.
Notes
- Decide the grain first (one row per sale, rolled up to product and to month) — it drives every trend card.
- Land raw tables first, then build clean Metabase models on top.
- Normalize sale-date, product, customer-email, gross-amount, fee-amount, and refund-status fields.
How should you model Gumroad data in Metabase?
Core tables
| Table | Grain | Key columns |
|---|---|---|
creator_orders | one row per sale | sale_id, order_id, created_at, product_id, product_name, variants, price, gumroad_fee, tax_cents, currency, subscription_id, is_recurring_billing, refunded, chargedback, utm_source, utm_campaign |
creator_products | one row per product | product_id, name, permalink, price, currency, is_subscription, published_at |
creator_members | one row per subscriber snapshot per day | snapshot_date, subscriber_id, product_id, status, recurring_charge, started_at, cancelled_at, ended_at |
Modeling advice
- Build a clean
creator_ordersmodel 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.
- Subscriber
statushas six values —alive,pending_cancellation,pending_failure,failed_payment,fixed_subscription_period_ended,cancelled— and only the first two are really active. Map them to anis_activeflag once so churn cards agree. - Keep
utm_sourceandutm_campaignon the sale row: Gumroad captures them at checkout, which makes launch and channel attribution possible without a separate analytics stitch. product.urlis deprecated and always returns null — don't model it, and ignore older tutorials that use it as a join key.- Store amounts in minor units or with an explicit currency column, and convert once in the model layer rather than per card.
Which Gumroad metrics should you track in Metabase?
| Metric | Definition | Notes |
|---|---|---|
| Platform fee rate | Gumroad fee plus tax as a share of gross sales. | Compute from the fee field, not the advertised rate. |
| Average order value | Average sale value by product and variant. | Pay-what-you-want pricing makes the median more useful. |
| Repeat purchase rate | Buyers who purchase again, by email. | Email is the only stable buyer key Gumroad gives you. |
| Churn rate | Membership cancellations over active subscribers. | Requires daily subscriber snapshots — the API is point-in-time. |
What SQL powers Gumroad dashboards in Metabase?
These assume a cleaned analytical model in a warehouse (PostgreSQL dialect). Adjust table and column names to match your pipeline.
What buyers paid, and what actually reached you.
SELECT
date_trunc('month', created_at)::date AS month,
COUNT(*) FILTER (WHERE NOT refunded AND NOT chargedback) AS sales,
ROUND(SUM(price) FILTER (
WHERE NOT refunded AND NOT chargedback
), 2) AS gross_sales,
ROUND(SUM(gumroad_fee) FILTER (
WHERE NOT refunded AND NOT chargedback
), 2) AS platform_fees,
ROUND(
SUM(price - gumroad_fee - COALESCE(tax_cents, 0) / 100.0) FILTER (
WHERE NOT refunded AND NOT chargedback
), 2
) AS net_to_creator,
ROUND(
100.0 * SUM(gumroad_fee) FILTER (
WHERE NOT refunded AND NOT chargedback
) / NULLIF(SUM(price) FILTER (
WHERE NOT refunded AND NOT chargedback
), 0), 2
) AS effective_fee_rate_pct
FROM creator_orders
GROUP BY month
ORDER BY month DESC;How much of a product's revenue arrives in its opening week.
WITH first_sale AS (
SELECT product_id, MIN(created_at) AS launched_at
FROM creator_orders
GROUP BY product_id
)
SELECT
o.product_name,
f.launched_at::date AS launched_on,
ROUND(SUM(o.price) FILTER (
WHERE o.created_at < f.launched_at + INTERVAL '7 days'
), 2) AS first_7d_revenue,
ROUND(SUM(o.price), 2) AS lifetime_revenue,
ROUND(
100.0 * SUM(o.price) FILTER (
WHERE o.created_at < f.launched_at + INTERVAL '7 days'
) / NULLIF(SUM(o.price), 0), 1
) AS launch_share_pct
FROM creator_orders o
JOIN first_sale f ON f.product_id = o.product_id
WHERE NOT o.refunded
GROUP BY o.product_name, f.launched_at
ORDER BY lifetime_revenue DESC;Checkout-time attribution, which most creator platforms don't capture at all.
SELECT
date_trunc('month', created_at)::date AS month,
COALESCE(NULLIF(utm_source, ''), '(direct)') AS source,
COUNT(*) AS sales,
ROUND(SUM(price), 2) AS revenue,
ROUND(AVG(price), 2) AS avg_sale,
ROUND(
100.0 * SUM(price) / NULLIF(SUM(SUM(price)) OVER (
PARTITION BY date_trunc('month', created_at)
), 0), 1
) AS share_of_revenue_pct
FROM creator_orders
WHERE NOT refunded AND NOT chargedback
GROUP BY month, source
ORDER BY month DESC, revenue DESC;What are common mistakes when analyzing Gumroad in Metabase?
Related
Related analytics
Related dashboards
Related integrations
FAQ
Does Metabase connect natively to Gumroad?
Should Metabase replace Gumroad's built-in reports?
Is there a Gumroad MCP server?
gumroad-mcp, but its last commit and release were in April 2025, so it's effectively unmaintained. Gumroad's own agent story is the Gumroad CLI, which the vendor describes as built for humans and AI agents alike — that or the raw v2 API is the route to use.Do I need a paid plan for the Gumroad API?
view_sales and view_payouts for read-only reporting access. One exception: /earnings is available only to US sellers with the Tax Center enabled, so derive earnings from sales minus fees if you're elsewhere.How do I track membership churn on Gumroad?
/products/:id/subscribers endpoint returns current status only, so churn has to be computed from the difference between consecutive snapshots. Map the six status values down to an active flag first — alive and pending_cancellation are still paying you. The membership growth dashboard shows the full card set.