How to share an Apache Superset dashboard
Superset's sharing story is the most self-hosted-shaped of any BI tool: every mechanism assumes the reader can reach your Superset instance and has a role in it. That assumption holds for the analytics team and breaks for everyone else.
What Superset gives you
A permalink. The share menu produces a URL that encodes the current dashboard state — applied filters, time range, tab. It is a genuinely useful feature and it is about state, not access. The recipient still logs in.
The Public role. You can grant the built-in Public role read access to
specific dashboards, which lets unauthenticated visitors of your instance open
them. It works, and it is a blunt instrument: it is a role on the deployment,
enabled globally in config, not a revocable per-link token. Teams typically
try it once for one dashboard, realize the blast radius, and roll it back.
Alerts & Reports. Scheduled screenshots emailed or Slacked on a cron. Real and dependable, and it wants a Celery worker, a beat process, a Redis or RabbitMQ broker, and a headless browser in the image. If your deployment already has that stack, this is the least-effort scheduled option. What you get out of it is a PNG: a record, not a document, and nothing anybody can quote a cell from.
CSV export per chart. Fine for one number. Not a way to send a dashboard.
The pattern that works for outside readers
Rebuild the dashboard's numbers as one self-contained HTML page and publish it to a stable URL with a comment layer on top.
The rebuilding is less work than it sounds, because Superset charts are thin wrappers around a dataset query. You have two clean routes:
Through Superset. POST /api/v1/chart/data runs a chart's query and
returns JSON, so a script that walks the chart ids on a dashboard gets every
number the dashboard shows.
Around Superset. The dashboard's underlying SQL runs against the same warehouse. If the numbers are the point and the Superset styling is not, query the warehouse directly and skip a dependency.
Either way, write plain HTML — inline styles, real <table> markup, no
runtime fetches — and publish:
python3 scripts/superset_digest.py > digest.html
curl -fsS -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
-H "Authorization: Bearer $COMMA_API_TOKEN" \
-H "Content-Type: application/json" \
-d "$(jq -n --rawfile html digest.html \
--arg title "Marketplace metrics — $(date +%F)" '{title: $title, html: $html}')"
Real text beats a screenshot for the same reason it does everywhere else: it is searchable, quotable, copy-pasteable into a spreadsheet, and readable by an answer engine. A PNG of a table is a table nobody can use.
What the comment layer changes
The published page carries anchored threads. Somebody highlights the GMV row and writes "this excludes the returns adjustment, see the note in dbt." That thread persists across revisions, so the caveat is attached to the number rather than living in one analyst's head.
Readers need no Superset account and no Public role, because access is a property of the report: private, team, domain-gated or link.
Keep the cron somewhere sensible
If you already run Airflow next to Superset, put the digest job there. If you would rather not own a scheduler for one report, a routine runs it on Comma's side and PATCHes the same report id, which gets you the stable URL and the revision history without the infrastructure.
When to just use Superset
If everyone reading has an account and the value is in pivoting — changing the filter, drilling into the cohort, exporting a slice — send the permalink. Interactive beats static whenever the reader can actually get in. The digest is for the audiences that cannot, and for the weeks you want a durable, dated, commentable record of what the numbers were.
Try it
Comma is free — unlimited reports, unlimited commenters, unlimited revision history.