Somebody asks you for dashboard access. It's your CEO, a board member, a client, an ops lead. They want to see revenue numbers, campaign performance, or pipeline metrics — and they want it live, not a screenshot from last Tuesday.
You know what you're not going to do: hand them a database connection string. You also know what's going to happen if you do nothing — you'll become the human reporting API, pulling the same numbers into a spreadsheet every Monday morning until you quit or automate yourself out of the loop.
The real question is which sharing approach fits the audience. A board member who checks metrics once a month has different needs than a client who expects a white-labeled dashboard inside your product. I've shipped all of these patterns, and they each solve a different version of the same problem.
The five approaches (and when each one fails)
Screenshot in Slack. Stale the moment you hit send. No drill-down, no filtering, no history. Fine for a one-off "here's where we are," terrible as a recurring workflow. If you're doing this weekly, something is broken.
Export to Google Sheets. Better than screenshots because at least it's structured data. But someone has to run the query, paste the results, fix the formatting, and remember to do it again next week. It breaks the moment that person goes on vacation. And Sheets has no concept of "this data came from a governed source" — anyone can edit the numbers, and now you're debugging whether revenue dropped or someone fat-fingered row 47.
Build a custom app. Full control, full cost. A React dashboard with its own API, auth, and hosting is a real engineering project — weeks of work for the first version, ongoing maintenance forever. Worth it if dashboards are your product. Overkill if the CEO just wants to see MRR without pinging you.
Use a BI tool and share its links. Metabase, Preset, Grafana — stand up the tool, build dashboards, share via the tool's built-in sharing. This works well when you already have a BI tool in your stack. It works poorly when the audience is external (clients, board members) and you don't want to manage seats or explain why the UI looks like a database admin tool.
Share dashboards with link-based access, embedding, or scheduled delivery. This is the approach that scales across all the audiences — internal stakeholders, external clients, board members. Let's break it down.
Approach 1: Public links with read-only tokens
The simplest sharing pattern is a signed URL. The dashboard lives behind your analytics layer, and you generate a link that grants read-only access to a specific view without requiring a login.
https://app.fastero.com/shared/d/abc123?token=sk_share_9f8e7d6c5bThe token controls what's visible. No database credentials leave your infrastructure. The viewer sees the dashboard in a browser — live data, auto-refreshing — and can't modify the underlying query or access anything outside the shared scope.
This pattern works for board decks ("here's the link to our live metrics"), client reporting ("bookmark this for your campaign numbers"), and internal stakeholders who don't need to build anything, just read.
Revoking access means invalidating the token. No password resets, no seat management, no "can you remove my old contractor from the BI tool" tickets.
Fastero
Connect your database. Ask questions. Get dashboards.
Postgres, BigQuery, Snowflake, and 10+ sources — live-connected, AI-powered, no dashboard builder learning curve.
Try free →Approach 2: Embedded iframes with row-level filtering
When dashboards need to live inside your product — a client portal, an internal tool, a partner-facing app — embedding is the right pattern. You render the dashboard in an iframe with parameters that control which data the viewer sees.
<iframe
src="https://app.fastero.com/embed/d/abc123?token=sk_embed_a1b2c3&filter_org=acme_corp"
width="100%"
height="600"
frameborder="0"
style="border: none; border-radius: 8px;"
></iframe>The filter_org parameter applies row-level filtering server-side. Acme Corp sees only their data. Your other client sees only theirs. The token is scoped to the embed — it can't be extracted and used to access the full dashboard or any other resource.
This is how most embedded analytics implementations work in practice. You're not building a BI layer inside your product. You're embedding a governed view of data that already exists, with access control handled by the analytics platform, not your application code.
The alternative — building your own embed with Chart.js or D3 against your API — gives you more design control but costs real engineering time. We cover that tradeoff in depth in how to embed analytics in your SaaS product.
Approach 3: Scheduled PDF and email reports
Not everyone wants a dashboard. Some people want a number in their inbox on Monday morning. Board members, finance leads, clients who asked for "monthly reporting" in the contract — they want a document, not an interactive tool.
Scheduled delivery solves this without making it someone's manual job:
{
"dashboard_id": "abc123",
"schedule": "0 9 * * MON",
"delivery": {
"type": "email",
"recipients": ["cfo@company.com", "board@company.com"],
"format": "pdf",
"subject": "Weekly Revenue Summary — {{date}}"
}
}The dashboard renders at the scheduled time, converts to PDF, and lands in the recipient's inbox. The data is current as of the render time — not a cached export from three days ago.
You can also push to Slack channels, which is the better fit for internal teams who live in Slack anyway. See automate SQL reports to Slack, email, and API for the full pattern.
The point is separating "who needs this data" from "how they want to receive it." The dashboard is the source of truth. Delivery is configuration, not code.
Approach 4: API-served data for custom frontends
Sometimes you don't want to share a dashboard at all. You want the data behind it — as JSON, over a REST API, so you can build your own UI or feed it into another system.
curl -H "Authorization: Bearer sk_api_x7y8z9" \
"https://app.fastero.com/api/v1/queries/abc123/results?format=json&filter_date_range=last_30d"Response:
{
"columns": ["month", "revenue", "new_customers", "churn_rate"],
"rows": [
["2026-07", 142300, 89, 0.031],
["2026-06", 138700, 76, 0.028],
["2026-05", 131200, 82, 0.034]
],
"executed_at": "2026-08-05T09:00:12Z",
"cached": false
}The query runs against your database. The API returns the result. Your frontend renders it however you want — a table, a chart, a stat tile in your product's dashboard, a row in a custom report. No iframes, no design constraints from the analytics tool's UI.
This is the pattern for teams building live KPI dashboards inside their own product. You own the frontend. The analytics layer owns the query execution, caching, and access control. Nobody touches the database directly.
Choosing the right pattern
| Audience | Best approach | Why |
|---|---|---|
| Board / investors | Public link + scheduled PDF | They want to glance, not explore. Monthly email is often enough. |
| CEO / leadership | Public link with auto-refresh | Live access, no training, bookmark and go. |
| Clients (external) | Embedded iframe with row-level filter | Data lives inside your product. Each client sees only theirs. |
| Internal ops team | Scheduled Slack delivery + link | Daily numbers in the channel, link for drill-down. |
| Engineering / product | API endpoint | They'll build their own UI or pipe it into an internal tool. |
Most organizations need two or three of these simultaneously. The CEO gets a link. The client gets an embed. The ops lead gets a Slack message. Same underlying dashboard, different delivery mechanisms.
What this replaces
Before I started doing this properly, my workflow was: someone asks for data, I run a query, paste it into Sheets, share the Sheet, then maintain that Sheet forever because people bookmarked it and expect it to update (it doesn't). Multiply by ten stakeholders and you've got a full-time job that produces no new analysis, just reruns of old queries with fresh dates.
The shift is treating dashboards as shareable artifacts with their own access controls — not as something that lives on one person's screen until they export it. Once the dashboard exists, sharing it should be a configuration decision, not an engineering project.
Where Fastero fits
Fastero handles all four patterns described above. You connect your database, build a dashboard (or let the AI generate one from a natural language question), and share it — via link, embed, scheduled email, Slack delivery, or API.
Row-level filtering on embeds means you can give each client their own view without building separate dashboards. Scheduled delivery means the Monday morning email goes out whether or not you remembered. API access means engineering teams can pull the same governed data into their own frontends without getting database credentials.
If you're looking at the broader question of self-serve analytics without the enterprise price tag, sharing is the last piece of that puzzle — it's the difference between "the data team built a dashboard" and "everyone who needs the data actually has it."
For teams building customer-facing analytics, the embedded analytics page walks through the embed pattern in more detail, including auth flows and multi-tenant filtering. And if your main need is live SQL dashboards rather than sharing specifically, build live dashboards from any SQL query covers the query-first approach.
Try Fastero free — connect your database, build a dashboard, and share it with a link in under five minutes. No credit card required.

