Let business teams refresh data without dbt Cloud seats
A simple screen where marketing and finance can see when each dataset last updated and hit Refresh now, with your data team looped in on Slack.
Build me an app that my marketing and finance analysts can open to refresh the data they depend on, without giving them dbt Cloud seats. The people using this are business users, not analytics engineers, so every label, status, and error message in the interface has to read in plain English. Never show raw job names, run status numbers, model names, or stack traces on the main screen.
The main screen is a list of datasets. Load the available dbt Cloud jobs with List Jobs, then show only the ones on an allowlist that an admin picks in settings. Each allowlisted job gets a friendly business name the admin sets, for example turning a job called daily_marketing_prod into Marketing Attribution. Each row shows the dataset name, the outcome of its last build, when that build finished in relative terms like Updated 2 hours ago, how long the build took, and a freshness badge that is green when the last successful build is inside the admin's staleness window for that dataset and red when it is older or the last build failed.
Get the per-row build history from List Runs filtered to each allowlisted job, ordered newest first, and use Retrieve Run when you need the full detail of a specific run. dbt Cloud returns run status as a number, so map it to plain language everywhere in the UI: 1 means Waiting to start, 2 means Getting ready, 3 means Building now, 10 means Up to date, 20 means Build failed, and 30 means Cancelled. Remember that dbt Cloud requires an account id in nearly every request path and wraps every response as an object with status and data, so read the payload out of data.
Every row has a Refresh now button. When someone presses it, ask them for a short reason in a small dialog, then call Trigger Job Run for that job. That endpoint is asynchronous: it enqueues a run and returns the new run id rather than waiting for the result, so the handler must then poll Retrieve Run for that id until is_complete is true. While it polls, the row shows live status moving through Waiting to start, Getting ready, Building now, and finally Up to date or Build failed. Keep the rest of the screen usable while a refresh is in flight, and let several datasets refresh at once.
As soon as a refresh is requested, post a note into the data team's Slack channel with Slack Bot Send a Message. The note names the person who asked, the friendly dataset name, and the reason they typed, for example: Priya in Finance asked to refresh Revenue Daily because the month-end deck needs today's numbers. The admin picks the channel in settings and can turn these notes off per dataset.
Rows whose last build failed get a Retry from failure button that calls Retry Failed Job, which resumes from the point of failure instead of rebuilding everything, and then polls the same way a fresh trigger does. Failed rows also open a detail drawer that explains what went wrong without requiring anyone to read logs. Populate the drawer with Retrieve Run Failure Details for the failed run, and use Retrieve Run Step to pull the specific step that broke along with its error text. Lead the drawer with a one-line plain summary of which stage failed, show the error text underneath for anyone who wants it, and include a Contact the data team action that posts the failure into the same Slack channel.
Bake in these guardrails. Never let a job be triggered while it is already queued or running: before triggering, check the job's most recent run and if its status is Waiting to start, Getting ready, or Building now, disable the button and show that a refresh is already underway, including who requested it if that request came from this app. Give the requester a rough sense of their place in the line by counting how many runs are currently queued or running across the account, and show something like Yours is second in line rather than exposing raw queue internals. If dbt Cloud returns an error, show a friendly message such as We could not start that refresh, the data team has been notified, and never surface a raw error payload to a business user.
Keep a per-user request history. Every viewer has a My requests view listing only their own past refreshes, each with the dataset, when they asked, the reason they gave, how long it took, and how it ended. Persist these records in the app so the history survives across sessions, and show a viewer's most recent request for a dataset inline on the main list.
Finally, add an admin settings screen where an admin picks which jobs appear in the allowlist, sets each one's friendly name and staleness window, chooses the Slack channel for refresh notes, and decides whether a reason is required before requesting a refresh and whether the retry button is available to all viewers or admins only.
What does this prompt do?
- Shows your data builds as plain business datasets, like Marketing Attribution or Finance Revenue, with a green or red badge telling everyone at a glance whether the numbers are fresh
- Gives every dataset a Refresh now button, so an analyst can update their own numbers instead of messaging the data team and waiting
- Follows each refresh live as it moves from waiting to running to finished, and shows roughly where it sits in the queue
- Posts a short note in your data team's Slack channel saying who asked for which dataset and why, so nothing happens invisibly
- When a build breaks, offers a Retry button and a plain-English explanation of which step failed, without anyone needing to read logs
What do I need to use this?
- A dbt Cloud account with the jobs your team relies on already set up
- A dbt Cloud service token, which you create once in account settings and paste in
- A Slack workspace and the channel your data team watches
- A few minutes to pick which datasets business users are allowed to refresh, and to give each one a friendly name
How can I customize it?
- Choose exactly which datasets appear in the app, and rename them from internal job names to language your business team recognizes
- Set how old a dataset can get before its badge turns red, for example one day for daily reporting or one hour for live dashboards
- Pick which Slack channel gets the refresh notes, or turn the notes off for low-stakes datasets
- Decide whether viewers must give a reason before requesting a refresh, and whether the Retry button is available to everyone or admins only
FAQs
Do my marketing and finance people need dbt Cloud logins?
Can someone break the pipeline by pressing Refresh too many times?
Will the data team lose visibility into what is happening?
What happens when a build fails?
Can each person see their own past requests?
How long does a refresh take?
Related templates
Stage a batch of filings overnight, then approve each completed form from a screenshot before anything is ever submitted.
Pick a client and a date range to see sent, replies, meetings booked and the real deal value your cold email produced, campaign by campaign.
Review every conversation Fin closed as resolved, judge which ones actually stuck, and see what the gap is worth against your bill.
Merge your IT, HR and Facilities queues into one list ranked by SLA time left, then reply, change status and escalate without ever opening Jira.
See every page's translation status at a glance, edit translations side by side with the English, and publish only what your team has actually approved.
One place for sales and ops to request an NDA or vendor agreement, watch its status, and let legal launch the contract in a single click.
Stop being the refresh button for your whole company.
Give marketing and finance a screen where they can update their own numbers, while your data team keeps full visibility in Slack.