Gumroad × Metabase

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.

Heads up: Metabase connects to databases and warehouses — it does not ship a native Gumroad connector. Gumroad's API is refreshingly ungated — a free token, no plan tier, and every sale carrying its own fee and refund fields — so the gap between “I want a dashboard” and “I have one” is genuinely one script and one CSV upload.

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.

1 · API + CLI route (AI-assisted)

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.

Best for
  • 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
Trade-offs
  • 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
2 · Pipeline route (warehouse-backed)

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.

Best for
  • 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
Trade-offs
  • 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?

For: Indie sellers, founders

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)
For: Marketing

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)
For: Founders

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)
For: Finance

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 csv to 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 replace or 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 csv needs 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)
ShellExample Gumroad API export
# 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.csv

Gumroad 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.

TerminalLoad a Gumroad CSV with the Metabase CLI
# 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.csv

Can 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.

Prompt for creating a Gumroad Digital Product Sales Overview dashboard
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

TableGrainKey columns
creator_ordersone row per salesale_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_productsone row per productproduct_id, name, permalink, price, currency, is_subscription, published_at
creator_membersone row per subscriber snapshot per daysnapshot_date, subscriber_id, product_id, status, recurring_charge, started_at, cancelled_at, ended_at

Modeling advice

  • Build a clean creator_orders model 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 status has 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 an is_active flag once so churn cards agree.
  • Keep utm_source and utm_campaign on the sale row: Gumroad captures them at checkout, which makes launch and channel attribution possible without a separate analytics stitch.
  • product.url is 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?

MetricDefinitionNotes
Platform fee rateGumroad fee plus tax as a share of gross sales.Compute from the fee field, not the advertised rate.
Average order valueAverage sale value by product and variant.Pay-what-you-want pricing makes the median more useful.
Repeat purchase rateBuyers who purchase again, by email.Email is the only stable buyer key Gumroad gives you.
Churn rateMembership 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.

Gross vs. net sales with the effective fee ratePostgreSQL

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;
Launch performance: first seven days by productPostgreSQL

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;
Attributed revenue by UTM sourcePostgreSQL

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?

Building on the community Gumroad MCP server.→ It hasn't been touched since April 2025. Use Gumroad's own CLI or the v2 API directly — both are maintained, and the API is free and ungated, so there's no advantage in the wrapper.
Paging /sales by incrementing an offset.→ It uses an opaque <code>page_key</code> cursor. Follow <code>next_page_url</code> from each response; incrementing a number silently returns the wrong pages or none at all.
Computing subscriber churn from a single API pull.→ Subscriber status is point-in-time — one pull tells you today, not what changed. Snapshot subscribers daily into a table and compute churn from the change between snapshots.
Building dashboards from live lookups only.→ Scripted exports are for exploration; durable dashboards need a database-backed model with history.

Related analytics

Related dashboards

Related integrations

FAQ

Does Metabase connect natively to Gumroad?
No. Metabase reads databases and warehouses. Land Gumroad data in a database first — via connector, API pipeline, or a direct database connection where the product allows one — or upload a CSV with the Metabase CLI, then build Metabase models and dashboards on top.
Should Metabase replace Gumroad's built-in reports?
No — they answer different questions. Gumroad's reporting is built for the operating surface it owns, and it's the fastest way to check that surface. Metabase is where you join Gumroad data with everything else — orders, customers, ad spend, support tickets, bank deposits — and define metrics once so every dashboard downstream agrees.
Is there a Gumroad MCP server?
Not an official one. A community server exists on npm as 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?
No. Generate an access token from your application page and you're in — no plan gating, which is unusual in this category. Scope it with 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?
Snapshot subscribers daily. The /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.