Currently in alpha. Sign up free. Expect a few rough edges.
Docs

Dashboards

Built by you or your agent, in your company's colours, on a phone. Every number carries its definition.

A dashboard reads a few named datasets (saved queries) and declares its numbers. A number is either a defined metric by name, or a formula over a dataset. The server computes every number and hands it back with a receipt: which definition, which version, whose words, which periods are too young to trust, and whether a model refresh failed. Its freshness line names the last good refresh and opens the failed run; Home counts the failed refresh too. The page draws; it never calculates.

The assistant builds a page from what you already have. A number one of your metrics answers reads that metric, so it is calculated the same way as on your other pages; a model that already cleans a table is read, not remade. A number nothing defines yet is worked out from a saved query the assistant saves of the rows it counts, with what it leaves out written in the query, and has a name of its own (order revenue, average order value). It makes no model and defines no metric to get a page up. When the page is up it tells you which of your metrics it used and which numbers it made as queries, and asks whether to define those as metrics; when two of the queries keep the same rows, it adds that it would recommend a model, now or later. Nothing is defined without your yes.

Say yes and it walks you through them one at a time: what the number is, how it is calculated, what is left out and which date it goes by. Your yes to that defines it, confirmed by you, and its card reads the metric from then on; the rest of the page is untouched, and the page's new version says what happened in Settings, Versions ("Order revenue now reads the metric Order revenue"). A yes that comes with a change ("yes, but leave out test orders") defines nothing until the changed calculation has been read back to you. If the number turns out to be one of your metrics already, the card is switched to that metric and nothing new is defined.

A headline card shows its figure, the change against a period it names, and a small trend line, and nothing else. Click it and the number opens beside the page, the same for everyone who can see it: the number, large, with its change; one sentence of what it is, with the days it covers and who confirmed it ("What customers paid for goods in September, after discounts and before shipping and tax. Confirmed by Sarah Bell."); one small line of what it leaves out, what it adds up and what it is compared with ("Not cancelled · each order's subtotal · vs August 2026"); and Ask about this number, which opens the chat beside the page already asking where it comes from (on full screen, the chat over the page). Show the rows, beside it, lists the first eight rows the number counts, with how many there are and Download all of them. A metric nobody has confirmed says how it stands on an amber line ("Defined by the AI in Sarah's chat on Oct 13, not yet confirmed"), and the people who build have Open the metric beside it. A number asked of a saved query says "A query, not yet a metric", and the people who build have Define it beside it, which opens the builder's chat on that number.

A small amber mark beside a headline means there is a doubt to know about: nobody has confirmed its definition, it is not a defined metric (the page or a saved query works it out), or its period, or the one it is compared with, is still settling (too early to trust). Point at the mark for which, or click the card. A period that has not finished yet is not marked, since a window such as the last 28 days always holds today; the card says so when you click it. A finished calendar month can still be too early to judge. A confirmed, settled figure has no mark, and a change is never coloured as good or bad news while either period is unsettled.

Month names and table headings follow the period the numbers came back for. A page showing September against August changes to October against September when its data moves on. The builder checks for typed month labels and asks for them to be tied to the returned dates before calling the page ready. A report for one fixed month can still request that month; its words come from the same returned period as its numbers.

A date on a page is the date of the data behind it. Some figures are a snapshot: receivables as they stood on the day of the last export. Their card says so, "As of Dec 31, 2025", and says the new day when the next export lands. A page that types a day over a figure like that is refused when it is saved, and so is a list kept to one snapshot day, which would go empty when the next one replaced it. For a day in the past, the figure is worked out from rows that carry their own dates: each invoice by its date, each payment by its date. A figure for a period still going, over rows that carry the report's own day (a weekly report's month so far), says how far it reaches: "Through Oct 12" under October, and under the quarter and the year that include it.

A number split by month keeps the months to come that have rows (next quarter's goals), and a month to come with nothing in it yet is empty, not 0. A number worked out from others (sales less the goal, by company) is empty, not 0, where the first of them has nothing to say: a month to come, or a company with no sales at all. The variance of a company with no sales yet reads "no sales", never "100% behind", and the number's receipt says so. A company that has sales in other months still counts 0 in a month it sold nothing.

Two figures that say the same thing count the same things. A win rate at the top and a win rate by salesperson both count quotes by the day they were decided, and a note that says which date a figure uses names the date it really uses; a page that mixes them is refused when it is saved.

A filter at the top changes every card under it, or a card says in its own words that it shows all of them ("all service lines"). A list of the biggest items is filtered first and cut after, so a service line shows its own 50 largest, not its share of the company's; the same goes for a long list that reaches the page only in part. Each of these is checked whenever a page is saved, from the builder, the command line, Claude Code or the API.

Money with credits in it is added up the way the page says. What a customer owes is their invoices less their credits and any payment not yet matched to an invoice, so a page that ranks customers by balance counts all of it, and shows credits and unmatched payments in a column of their own. Open invoices before credits is a fine figure too, when the page says that is what it shows. A page whose words promise one while it adds up the other is refused when it is saved.

A page can also take records in: a form that adds a row to a table you fill in yourself (log a store visit) and the list of its rows beside it, anyone who can see the page adding with their own name on the row. The page's numbers and lists move as soon as a row is in.

A gap is checked against the data before a page is saved. If you asked for a page while a month was missing from an export, and the month has arrived since, the page shows it; it may say the month was missing from the first export, but it never hides a figure the data has.

Finding one

Dashboards lists every dashboard and report. With nothing in it yet, it is the title and Your first dashboard, whose button, New dashboard, is the one on the screen; the search, the tabs and the menus come with the first dashboard. Search it, or narrow it by folder, by who made it, by status, or to dashboards or reports only, and sort it. The Folder menu also has New folder and Manage folders, which open the list of folders to add one, rename one or delete one (what was in a deleted folder stays, unfiled). What you pick is kept in the page's address: open a dashboard and come back, reload, or send someone the link, and the list is the same. Cards or a table is remembered by your browser. A card shows a picture of the page it opens: the published version, or the newest one saved while nothing is published. The picture is taken by itself, once for each version: when the version is published in the app, or the first time someone who can build dashboards has it open there on a full-size screen (a phone's is too narrow for it). A dashboard pushed from a laptop gets its picture that way, at its first open in the app. Until then the card shows the page drawn small, a stand-in in the app's colours, where the picture will be. The picture shows the numbers as they were when it was taken; open a card for the page itself, with its numbers as they are now.

Someone in a group (a client looking at the dashboards shared with them) opens on their dashboards, with none of the builders' controls: the pages they starred first, under Starred, then each folder in its order, then the rest. Each card is the page's own picture (the page drawn small until it has one), its name, the star, and one line: its headline and when its numbers are from, "Net sales $293,682, up 20% on last year · 6:36 pm". The headline is the page's first single figure that is compared with another period, else its first single figure; a filter the page adds is said ("Net sales (online only)"); a page whose numbers are all split by something says only "Numbers as of 6:36 pm". The line is worked out when someone opens the page and again every night, so it is never more than a day old.

A page they open has one bar over it: where they are (Dashboards / Online) and, at the right, when its sources were last checked and what changed since ("Pipedrive checked 2:05 this afternoon, nothing new since Monday"), Download and Full screen. The bar warns only when something is wrong, with a dot and the words in their place: a number that failed, in red ("1 number failed: Wholesale past due"), or a source the page reads that is behind, in amber ("Shopify last synced 3 h ago"). A number with no data for its period, or a list with no rows, says so on its own card and nowhere else. Busy, trying again on a card means four questions were already running on your machine; it retries on its own, every few seconds, and the number takes its place when it comes. After half a minute it says Busy, with a refresh beside it that asks again. The page says its own title once, below it; none of the lines that are for the people who build it (the version, who published it, the requests for data, the tabs). On a phone the bar is the back arrow, the page's title and Download, and the page takes the screen.

A page asks for all of its numbers at once, as one request, and draws itself whole: while its numbers are on the way every card shows the grey shape of what is coming, never an empty board or a table that says there is nothing, and a busy moment holds the whole page a few seconds longer rather than filling it in pieces. At its foot the page says when its sources were last checked and what changed since ("Pipedrive checked 2:05 this afternoon, nothing new since Monday", or "new rows at 1:40 pm"), the same words the bar says, so a page opened from a link or shown full screen says it too. A check is a pull that finished, whether or not it found anything new: a page with nothing new for days still says it was checked today.

The people who build a page see the same bar with Build with the agent before Download. It says the page's state before when its numbers are from ("Published · Numbers as of 2:16 pm"). Under the bar are the page's title and its one line, said once, and, only when something needs doing, a link that says what ("4 numbers aren't metrics yet", or "1 metric isn't confirmed") and opens the tab where it is done. Then three tabs: Overview is the page itself; Where the numbers come from starts with the one thing to do, when there is one ("4 numbers on this page aren't metrics yet." and Define them), then lists each card and chart on the page once, in its own words and in the page's order (a headline and the small trend line under it are one row), with one sentence of what it reads ("The metric Order revenue, confirmed by Sarah Bell, from files.orders"; "A query, not yet a metric, from files.lines"), every name in it a link: a metric opens beside the list, a table opens in Warehouse. Click a row and the page opens with that card's pop-out open, or, for a chart or a table, with the card ringed for a moment; Settings has every version, with who saved and who published it, and Real time, the notes, the theme and the files. A version pushed from a folder on a laptop says so there, since the next push from that folder overwrites what is changed in the app.

Press ⌘K (Ctrl+K on Windows) on any screen and type a dashboard's title. Choose it and it opens. The same box finds a monthly report by its month and a metric by its name, jumps to a section or a table, and starts this month's report (Write this month's report). It lists only what you can open.

Full screen, at the end of the bar above a dashboard, opens the dashboard's own page in a new tab: the page alone over the whole window, nothing above or below it, numbers and all, at an address of its own (/<company>/dashboards/<page>/full). The address in the browser's bar is the one to send someone: a report email's Open the dashboard goes there too. The Ask bubble floats over the page's corner as everywhere. Reached from inside the app, a small Exit full screen (or Esc) floats at the top right to come back; a real-time page's mark and Sound float there too. If a page does not start, it says so where the page would be, with Open the frame alone, to see why.

Under a table on a dashboard, Download saves what the table shows, as Excel or CSV: the period and choices the page is set to, a drill-down you opened, your search, your sort, and the columns in their order. It is worked out again for you, with your access, so it holds every row that matches, up to 20,000, not only the rows on the screen. Its first lines say which dashboard and table it is, the period, the filters, how fresh the data is, whether it is every matching row, and who downloaded it when. A table of rows the page put together itself has no Download. Someone in a group downloads only what their dashboards show. A download counts toward your plan's daily allowance for data sent out.

Money is money on a page. Amounts kept to the cent, such as QuickBooks' invoice totals, reach a dashboard as numbers: a table shows them as its column says (dollars where it says so), lines them up on the right and sorts them by size, and a chart can draw them. A download of the table keeps every digit, in the order the table shows. In the chat, a table's column named like one of your metrics is shown in that metric's format, so the table reads as the answer's words do.

Building one

Before you publish, the checklist gives each number its plain name and says whether its definition is confirmed or a guess. Open Where it comes from for the period, tables and row count.

The same question says first what this version changes against the version live now, whatever was published since the draft was started: a row for each change, under Calculation (a figure added or taken away, its definition, filter, period or split, a saved query the page reads) or under Presentation (the layout, the colours, shown as themselves, the theme, the title). A first version, or a page that was unpublished, has nothing to compare with, and the question says so. The agent says the same when it publishes for you.

Describe it. "A sales dashboard by product and region, refreshed each morning, with net revenue and returns shown separately." Your agent, or you, builds the page from the datasets. Asked to build something that already exists, the assistant offers the existing one first and builds another only if you say so. Every save is a draft only you and admins see. Publish, beside "Not published" at the top of the page and on the build page, makes it the page everyone sees. Nobody has to open a version first: it is ready as soon as it is saved, and waits only when the page reported a problem or the version waits for you to press Load ("Load it first"). When nobody has opened the newest version yet, the line beside Publish says so ("Version 4 is not opened yet: open it"), and Publish works all the same. Its Settings tab's Versions is the page's history: the live one marked Live, the newest Draft, and Go back to this version on one that was live before, after saying what going back changes.

A page can start from the starting page a source ships. Pipedrive's is Pipeline, with every open deal by stage, what each is worth, when it should close, and who to call, and every contact on a second tab. The source's own page offers it once its first pull has landed, and a yes makes a draft only builders see, which you change and publish as any draft.

If someone saved a newer version while you were editing, the save says who and when, and you choose, look at theirs, save over it, or take theirs. On a laptop, ovs push says pull first and ovs pull merges.

A page can also be written on your computer, in a folder ovs pull made, by you or Claude Code. ovs dashboard preview <slug> shows it in your browser before it is pushed, in the same frame and with the same numbers the app would show, and ovs dashboard look <slug> takes the pictures the builder takes of its own pages and says what is wrong. ovs push then saves it as a draft, as any save is.

A page can start from an answer. Under a table or a chart in a chat, Put this on a dashboard makes a page of it, named after it and asking for the same numbers the same way, or adds it to one of your pages. A headline comes with a chart of its trend beside it. The builder opens on the page and looks it over first, changing nothing until you ask; nothing is published until you say so.

To take a page out of circulation without deleting it, choose Unpublish on its card's ··· menu, or on its live version in Settings, Versions. Viewers stop seeing it: it leaves their dashboards, the search box and the chat, and its link tells them it isn't published. It stays here as a draft for the people who build, with every version, its folder, everyone's stars and the groups it is shared with, so publishing a version again gives the same people the same page. Delete is for a page nobody should see again. Unpublishing is recorded as an admin action, with who did it.

New dashboard asks what it is called. A name a dashboard already has is never opened in its place: the form says the name is taken, offers Open it for the one that is there, and puts a free name in the box ("This month 2") so you can build yours. Names are compared by their letters and digits, so "Sales Weekly" and "Sales / Weekly" are the same name. The chat beside a dashboard you are building works on that dashboard: what it saves lands there, where you are watching, and it starts another page only when you ask for one ("put the stores on another page"). A page a chat built from Chats opens in the builder with that same chat beside it: what you and it said is there, and from then on it can look at the page.

To change the rows a draft reads without changing the published page, use a new saved-query name. If an existing query is used by a published page, changing its SQL is refused and the response names those pages. Save the changed query under a new name, point the draft to it, then review and publish. An intentional replacement through the API can change every page that reads the shared query immediately. The source rows still update as new data arrives.

Each dashboard version keeps its own theme settings. Changing the draft's colours or fonts does not recolour the published version or earlier versions. A save without theme settings keeps the latest draft's settings; the company theme still supplies defaults.

On your phone

A dashboard is one page, and it rearranges itself for the screen it is on. On a phone its cards stack one to a row, charts shrink to fit, and a wide table scrolls sideways inside its own box. The app gives the dashboard the screen there: the back arrow, the title and Download on one line, and for the people who build it the page's three tabs under it. A dashboard with tabs shows them as a bar along the bottom, the way an app does, and the arrow at the top left takes you back to your dashboards. Nobody builds a second version for phones, so there are never two copies to keep in step.

A headline figure always fits its card. When six cards share a row, a figure like $7,748,750 gets a little smaller, or reads $7.7M with the exact amount when you point at it. A caption or a name too long for its card is cut to one line; point at it, or click the card, for the rest, so the cards in a row line up. A chart's dates thin out on a phone, every second or third month with the latest one always shown, so the labels never run into each other; point at the chart for any month.

On a phone, the builder preview lays out the page at the available width. The agent reviews it on a big screen and at a phone's width, checks that small labels and brand-coloured words are readable, and fixes anything cut off at the right. Ready means both reviews pass. The agent reviews a page from its builder: a page the assistant makes in a chat you started from Chats isn't looked at there, and its answer says so, with a link to open the page in the builder and check it before you share it.

No math on the page

A version goes live the moment you publish it, whether or not anyone has opened it: from the builder, from the page's own bar, or from Claude Code or the command line (ovs dashboard publish <slug>). A version saved from Claude Code or the command line comes back with the link to see it in the app, under your company's name at app.overscore.tech (ovs push prints it). If a published page breaks later, the nightly check finds it and the Inbox tells you.

Publishing never waits on metrics. The question says, in the cards' own words, which cards add up their own rows ("Net sales by week adds up its own rows; every other card reads a metric."); publish, and sort that out afterwards on the dashboard's Where the numbers come from tab. Each card there says what it reads, and whether a person has confirmed it. A card whose number is asked of a saved query, or that draws a saved query's rows, says "A query, not yet a metric", and the tab leads with how many there are and Define them: that opens the builder's chat on all of them, which takes them one at a time, reads each back to you and defines it on your yes. With every number a metric, the tab says how many nobody has confirmed ("1 metric on this page isn't confirmed.") and Confirm it opens that metric beside the list. A metric the assistant saved in a chat and nobody has confirmed says "not yet confirmed" in its row, and the metric itself says how it stands ("Defined by the AI in Kim's chat on Oct 13, not yet confirmed"). The card itself carries an amber dot only for a metric nobody has confirmed; a card on a query carries none, since the tab says it. When a card's own sum is a metric you already have over the same rows, the builder's chat says so after a build and switches it on your yes. A metric defined later that computes the same thing links by itself. A metric's version is said only when two of its versions are on the same page.

Every number on a page has a trace: how it's calculated, the amount sent to you, its dates and split, and the exact SQL with the clock recorded when it ran, the tables it read and their status, and when it was last sent to a page. Whoever may see it opens it from the number's pop-out, under Prove it; an agent asks for it by the number's name, so "where does this come from" is answered the same way in the app, in a chat, and from a laptop.

A page only shows numbers the server worked out. "Up 6% vs last year" is asked for with the number and comes back with its own dates and SQL; a ratio like average order is a defined metric, not sales divided by orders on the page. Every save is checked the same way whoever saves it, from the builder, the command line, Claude Code or the API: a page that adds up, averages, divides or subtracts figures in the browser is refused with the file and line, and what to ask for instead.

Define it later, and it still links

The same goes for chat answers. When a metric is defined, the assistant's own queries from the last six months are read again; one that computes the new metric is linked to it, and a check of that answer says "worked out by hand when it ran; since then the defined metric computes this". The old answer is never rewritten.

When the new metric is close to what a page works out but not the same (the page averages, the metric divides the totals), an admin gets one card with both figures and three answers: switch the page's number to the metric, keep the page's own calculation for now (about this version of the metric only; a new version asks again), or define the page's calculation as a metric of its own. The metric's page lists every page linked to it or kept against it.

A number worked out on a page today can become a defined metric's number tomorrow, with no change to the page. When a metric is defined, or a new version of one is saved, every page number built before it that computes the same thing is linked to it on its own: from the next load it shows the metric's number and receipt, and its trace says when it was linked and that the link came after the number was first shown. A number that is the same calculation over fewer rows (one rep, one channel) becomes a card for an admin: Use the metric links it, asked with that filter, and the receipt says so. If a later version of the metric stops computing what the page does, the link is undone and a card says why.

What was shown, and every version

Every number that goes to a page is recorded as it goes: the page, its version, the number, the value when it's a single figure or a short list, and which version of the metric or saved query it came from. So "what did that page show on the 3rd" has an answer. The value on a number's trace is the one your own page last got; who saw what across the company is the admins' record. Saved queries keep every version of their SQL, and a receipt names the version a page read. Deleting a dashboard takes it out of every list and unpublishes it, and everyone's stars on it go; its versions and the record of what it showed are kept, and saving a dashboard again under its name brings it back with its earlier versions. A deleted saved query is hidden the same way, its versions kept.

Charts follow the same rule as headlines: the query groups the rows (by week and channel, say) and the page only lays them out. A page that groups and adds rows up itself is refused at save.

Worked out once, kept until the data changes

A number is worked out once and kept. Everyone who opens the page after that is handed the same answer, so the tenth open is as quick as the second. It is worked out again when the data it reads changes: a sync lands rows, a model is rebuilt, a file is loaded, a row is marked. The same goes for the rows of a saved query, and for the numbers in an alert or an email: the same metric on two pages, or on a page and in an email, is one answer.

A number is never more than five minutes behind its data, and usually much less; a model's rebuild shows the moment it finishes. After rows land, the numbers on every dashboard someone opened in the last two weeks, on every alert that is on and in every scheduled email are worked out again on the worker that landed the rows, right after the models over them are built, before anyone looks. A dashboard nobody has opened lately is worked out on its next open. A card worked out on a page over a saved query reads that saved query's kept rows, so a page with five cards over one saved query runs it once. Your tables' files are kept on your machine's own disk once they have been read, and merged into one file per table after every pull, so a query that has to run reads from disk, not from storage file by file. The line under a dashboard says when its numbers were worked out, after when its data last arrived: "Numbers as of 6:02 this morning (Stripe), worked out 9:02 am".

A number that follows the day (this month, the last 7 days) is worked out again each day. A fixed period, such as March 2026, stays as it is until its data changes. Two people who may see the same data share one answer; someone who sees a dataset masked gets their own, from the masked copy. Run it again on a number's trace always works it out fresh, and the page shows that from then on.

Three kinds of answer are never kept and are worked out on every open, as before: one that reads another database in place (a live Postgres link), because nothing says when its rows change; one whose SQL uses the exact time, such as now(); and one too big to keep, over about four megabytes of rows.

A page refreshes itself

On Self-serve and Done for you, live updates are on by default for every dashboard. A dashboard on a screen refreshes on its own when its data changes. When a sync lands, a model is rebuilt or a sale comes in through a webhook, the numbers that read those tables are asked for again within a few seconds, and the cards that changed settle in with a short fade. Nothing to press. A tab you hide hears nothing while it is hidden, and catches up the moment you come back to it. A page published before anyone opens it follows the tables behind its metrics too. It needs no first visit from a builder. On Free a page refreshes when you reload it. Opening or reloading compares the data behind each number now, including any small table kept in your browser. An unchanged answer is reused without waiting five minutes.

Whatever writes a table tells Ably, a service that holds every open dashboard's connection, and Ably tells the open pages that read it. The page then asks your company's machine for its new numbers. News that cannot reach Ably is saved for a worker to send, even if the machine that wrote the table stops. An open dashboard makes no repeated checks, so your company's machine can sleep between changes. The page catches up when it opens or reconnects. Ably is told which table changed, when, and how many rows, never a row or a number, and each person's page hears only the data that person may see. Every figure is still the server's, with its receipt and its trace.

Numbers worked out in your browser

Most of a page's numbers are sums and counts of a metric over a table, cut by day and by the things the page splits or filters on. For those, the server builds a small table beside the page (a few thousand rows, usually under 100 KB) with the same rules the metric has, and your browser works the number out from it. Pick a channel, a region or a rep on the page and every number follows at once, with nothing asked of the server. The metric is still defined once, on the server. The figure is the same figure, with the same receipt, and Prove it still runs on the server. A number that cannot be worked out that way (a median, a distinct count, a hand-written query, a split compared with an earlier period, a table too big to send) is asked of the server as before, and the page's Where the numbers come from tab says which is which. The first open of a dashboard downloads the engine that does this, about 5 MB once, kept by your browser, and nothing is fetched from anywhere but Overscore. Someone who may only see part of a table, or a masked copy of it, is never sent the small table and keeps asking the server. When the data under the page changes, the small table is built again and the page takes the new one as any card refreshes, and only people who may read that data hear of it. What your browser keeps is kept for you alone, for this company and this dashboard, and a small table that was built again while it was on its way is asked for again rather than shown as the one before.

Real time

Real time is the live look on top of that, for a page that watches rows land all day, a sale at a time. Turn it on in the dashboard's Settings, under Real time. Then each new row that comes in through a webhook, or that a script of yours or a command at the terminal writes, is marked on the page within a second or two, and the numbers it changes follow at once rather than settling after a few seconds.

  • An admin turns it on or off, on Self-serve and Done for you. Everyone who can open the page sees it as it lands, someone in a group too. On Free a page refreshes when you reload it. Opening or reloading compares the data behind each number now, including any small table kept in your browser. An unchanged answer is reused without waiting five minutes.
  • Writes land in spurts, and the page shows them that way. Rows that land within one second reach the page together, with their count. The numbers are asked for again at most once a second, however fast the rows come, and one number is worked out once for every screen showing it.
  • A page can mark each new row as it lands: a small +1 rises from the corner of the figure it landed under and fades (+12 when a sync brings twelve rows at once), and when the server's new figure arrives its digits roll to it. The +1 is a mark, never a number on the page, and the figure is always the server's. Most figures come from a model, built from the tables rows land in: the +1 shows the moment the row lands, and the figure moves when the model has been built with it, usually a minute or two later. Ask the builder for it on a real-time page.
  • A page that marks new rows can ding as they land. Sound on, beside Full screen, turns it on for you on that page, in this browser, and plays the ding once so you know what to listen for; it changes nobody else's screen, and it is off until you press it. On a later visit it plays again from your first click on the page, which is when a browser allows sound. In a spurt the dings come as a quick run, never a wall.
  • The line above a real-time page says Real time where any other page says Live, with when the last new row landed ("as of 10:42:07 am"; before any has, "as it happens"), and the page's Full screen keeps it in its bar, with Sound on beside Exit, for a screen on a wall. When the page stops listening it says so in amber, in a few words: Real time off · an admin turns it on in Settings when it was turned off, and Real time reconnecting… while a lost connection is tried again. Point at the line for the whole reason. The figures stay as they were until it listens again.
  • A page nobody has open listens to nothing, and a tab you hide stops listening at once and catches up when you come back to it.
  • A page that reads another database in place (a live Postgres link) cannot be real time, because nothing says when its rows change; the setting says so. A real-time page changed to read one stops being real time when that version is published, and the page says why. Copy those tables into the warehouse on a schedule and the page can be.

Download a page

Every dashboard has Download at the top: beside Build with the agent for whoever builds, beside Full screen for someone in a group. This page as a PDF puts the whole page, top to bottom, on one page of a PDF named after it and the day ("Online 2026-10-10.pdf"), always on a light page, even when your screen is dark. Under it is each table on the page, by the heading of the card it sits in, once as Excel and once as CSV: a table the page shows comes as it is on screen, with its search, its sort and its columns; a table or chart the page draws itself comes with the columns its card shows when the page names them, under the card's heading, else whole, every column, under the list's own name; a card that shows the first few rows (Recent emails shows 8 of 30) gives those rows, when the page says how many. Each file starts with what it is: the page, the period, the filters, how fresh the data is, and whether it holds every matching row (up to 20,000). On a phone the menu opens along the bottom.

Someone in a group downloads only what their page asks for, with the page's own access, as they read it.

Prove it

Admins, the people who build, and anyone in a group an admin has given Proof have one more small link at the foot of a number's pop-out: Prove it. It opens the proof in the same pop-out, in two sentences: what went to your page, when, who asked and which version of the page ("$412,380.42 went to this page today at 2:16 pm, asked by Sarah Bell, page version 3."), and what it is and what it read ("It is the metric Order revenue, read from files.orders, an uploaded file added today at 9:40 am."); the metric's name opens the metric, the table's its page in Warehouse. Run it again runs the same query now, as you, and says what it found against what went to the page ("Run again just now: $412,380.42. No difference."). The recorded query and clock stay fixed, but new or corrected source rows, or changed access, can change the result; if an older number did not record its clock, the proof says why it cannot run it again. Show the query is the SQL as it ran, with Copy. A saved query's own totals show that query's recorded version and SQL.

A number's pop-out is in plain words for everyone, with no calculation and no SQL: what it is (its definition, and a filter the page adds said in the same sentence, "This page counts only rows where channel is online."), the days it covers and who confirmed it, by name. A period that isn't over yet says so on an amber line. Download all of them, under the rows it shows, saves every row the number counts as an Excel file, up to 20,000, whose first lines say the page, the number in the same plain words, the period and that it holds every row. Someone in a group gets Prove it, which carries the SQL, only when an admin ticks Can see where numbers come from on their group (Members, Groups, under Proof); then the names in it are words, not links, and it proves only the numbers their page itself shows. With Proof off, the dashboard’s number and query responses leave out the calculation’s SQL and source details. Its values, dates, comparisons, trust warnings and allowed rows stay available.

Where a page came from

Under a dashboard's title, and on a model's page, one line says where the current version came from: a chat, the app, or a folder on someone's laptop (ovs push). A version pushed from a folder says so, and that the next push from that folder overwrites what is changed in the app, so nobody edits a page in two places without knowing.

The rows behind a figure

For a metric or a formula, the pop-out offers "Show the rows": the rows that number adds up, read as you. It is the same query with the adding-up taken off: the metric's table, its always-on filter, the period the page asked for, and, when you clicked a bar or a row, that point put back as a filter, so the August bar of net sales opens August's orders and Ann's row of commission opens her lines. A number switched to a metric opens that metric's rows and filter. A total worked out inside a saved query (a column of its table on the page) has its rows too, through the page's own clicks or an agent, though the pop-out offers Show the rows only for a metric or a figure the page works out; a clicked row of it opens just that row. A cumulative number opens its whole window: March's year-to-date includes January through March. The count counts each source record once, even when it contributes to several running totals. The pop-out shows the first eight, with how many there are; an agent can read up to 500. A page can offer the rows on its own clicks too, and an agent asks for them by the number's name, so "which orders make up that number" has one answer everywhere.

When you tick a checkbox or change a status on a dashboard, the page asks for its tables, numbers and open row lists again after the mark saves. A count of unfinished orders and its rows catch up together; you do not need to reload the page.

Reports

Reports is the third of the Dashboards list's own tabs, after All and Dashboards, and the tabs show once a report exists: before that All and Dashboards are the same list. The first monthly report is written from ⌘K, Write this month's report, and an analysis is saved from a chat. It holds two kinds of page, and each card says which in two words, with who made it and its first sentence.

A Monthly report is written each month from your numbers. Write this month's report is the button on the tab, and before the first one the tab says what one is, with the button under it. Before there is any dashboard the tabs wait too: ⌘K's Write this month's report opens the tab. It opens on a page of its own: the month, who asked for it, when it was written and how far its numbers run, then the report, with the numbers it was given folded under it. Email it sends it now to the people you pick. A monthly report holds every metric's figures, so it is never shared with a group.

An Analysis is a dig someone did, kept whole and frozen: the question, every step of the work in order (each query with its SQL, rows and time, each metric with its receipt, each table or chart kept), the tables and charts it ended with, and the conclusion. Opening it later shows exactly what it showed; it never reads your data again to draw itself.

Making an analysis

  • In a chat: Save as an analysis, first in a table's Keep or share or in the chat's ···, or say "save this as an analysis called X". The whole chat is kept, its last answer the conclusion.
  • In Claude Code or any agent: ask it to do an analysis. It starts one, every query and metric it runs from then on is kept as a step, it keeps the tables and charts that make the point, and it saves the analysis with its conclusion. See Use with Claude Code.
  • From the command line: ovs analysis start, your queries, ovs analysis keep, ovs analysis save. See the CLI reference.

An analysis's page

The title, what was asked, who kept it, when, and how old its numbers are; then the conclusion, with each table or chart where the words put it and the others after it; then The work, folded: a row for each step, in order, which opens whole in the side panel with its SQL to copy.

Run again asks every table and runs every step again as you, today, and keeps the result as the next version. A table asked for a time that moves (last month, the last 28 days) is asked for the same days it showed: kept in September, last month is August, and run again in October it is still August, its title saying so. For the new month, pick it up and ask. The words stay as they were written, and the page says the day they are from. A table that cannot be asked again (its table was dropped, its metric removed) says so in its place, with the version that has it as it was. Only queries that read are run again, never one that changes data.

Pick it up opens a chat that starts from the analysis: the assistant is told every step, table and the conclusion, so you carry on where it stopped. Save that chat as an analysis and it is the next version, its earlier work kept first. An analysis keeps twelve tables and charts at most: past that, the new version keeps the newest twelve, and its page says which were left out. Claude Code and the command line pick one up too.

Versions lists every version: how it was made, by whom, how old its numbers are and when its words were written. Each table's Keep or share puts it on a dashboard, downloads its rows as Excel or CSV (the rows the analysis kept, with the day they were taken and their definition in the file), and shows where it came from, down to who wrote its query: the assistant in a chat, Claude Code, another agent or the command line, by name for a person ("A query Kyle Malone wrote at the command line"), so it reads true to whoever opens it later. Download gives the whole work as a zip of folders and files. Email it sends the conclusion with each table's figures as kept, and a link to the page.

Share, for admins, picks the groups that may open it, every version of it. Their people read the words, the tables and charts, and each step in words, never its SQL. Otherwise an analysis is its maker's and the admins'.

If a link points to a report or an analysis that is no longer available, the page says so and offers Back to reports, where you can choose another.

Who sees what

Everyone in the company is one of three. A viewer opens every published dashboard and the chat about them, and nothing that builds: no tables, no SQL, no files, no sources, no keys. A builder builds dashboards, models and sources, and sees everything. An admin does everything a builder does, and changes the company's settings, people and keys. Add a person, under Members, People, asks which one.

A viewer sees every published dashboard until you put them in a group. A group narrows a viewer to the dashboards it is given: open the person's row, pick the group under Sees, Save. A group is a name, its people, and what is shared with it: whole folders (the dashboards put in a folder later come with it), single dashboards, extra metrics, and analyses (from the analysis's own Share). The metrics and saved queries behind those dashboards come with them, so nobody keeps that list by hand. A person is in one group.

What comes with a dashboard is what its published version names: the metrics and saved queries written into the page. Trying another number on a shared page while you build never shares it, whoever tries it. A page that picks its metric as it runs, from a list on the page, does not name it; share that metric with the group as an extra.

  • Viewers is the built-in group every viewer starts in: every published dashboard, never a draft. It has nothing to tick but the extra metrics its chat may answer from, and Proof. (It was called Starter, which is also a plan's name, and then New people.)
  • Everything is where the builders and the admins are. An admin is always in it; a builder is a member in it. To let someone change the company's settings and people as well, make them an admin: Make admin on their row, once they have come in, or add them as an admin to begin with.
  • Any other group (Reps, Store managers) sees the published dashboards and the analyses shared with it, the numbers on them, and nothing else. A viewer's app shows only what they can open: Home, with the pages they starred and their chats; Dashboards; Chats; and their own account under Settings, where their alerts and emails are.

A sales rep in a Reps group that has the Sales folder opens the commission dashboard and never sees the finance one. The page shows them what it shows everyone, so whoever builds a dashboard decides what its numbers and tables show that audience. Their page answers only what that page asks for: a request made by hand for another metric is refused, in a sentence that says what the page does show.

They can ask any metric of their group for another period, or by any split the metric is declared safe to cut by, and filter it on those same splits. An alert or a scheduled email they set up reads only those metrics and goes to them alone. They have no Alerts or Emails screen and no tabs above their dashboards: theirs are under Settings, Account, one table of both, each with its last checks or sends, Pause and Delete.

Behind a number on their page they can see the rows it counts and download them all, from Show the rows in its pop-out, by the same rule as the page. Where the number comes from (the amount sent, the tables it read and its SQL, under Prove it) is for the people who build, and for a group an admin gives Proof.

An admin narrows a viewer under Members, People: open their row, pick the group under Sees, Save; Every published dashboard there puts them back in Viewers. The same row changes a viewer into a builder, and back. Add a person there asks for the address and the role, every time (Viewer, Builder or Admin, with one line saying what each opens), sends the invitation, as a member or as an admin, and saves the role against the address, so it applies from their first sign-in. Before their first visit, the row shows the current invitation status. If it expired or was taken back, open their row and press Resend invitation. Their saved group stays the same. A failed status check says it could not check.

Removing someone on People stops their next signed-in request and their person and laptop keys. This includes admins. They stay removed until an admin adds them again.

Groups are made and changed under Members, Groups. The Metrics count includes the metrics behind its dashboards and its extra metrics, counting each once. Open one to see its people. Remove puts someone back in Viewers, where they see every published dashboard. Add a person lets you choose someone already listed on People. Invite a new person opens People’s invitation form. Tick the folders and dashboards it is given, and any more metrics its chat may answer from. One line under the dashboards says what they come with: the metrics and saved queries behind them, worked out for you. Under Proof, one tick, Can see where numbers come from, adds Prove it to the numbers on their dashboards: the amount sent, the tables it read and the query. Admins and the people who build have it without a tick. Delete group sends its people back to Viewers. Everything has everything, so it has nothing to tick; Viewers has every published dashboard, so it has only the metrics and Proof.

To check what someone sees, open their row under Members, People and press See as. The app opens as they get it, with a strip across the top that says whose it is, and Stop. It only reads: anything that would change something is refused, nothing is saved as them, and what you open is recorded under your own name, with one line in Settings, Activity saying you saw the app as them.

What their chat can do

On Self-serve and Done for you everyone gets the chat. For someone in a group it answers from that group's metrics, by any period and any split a metric allows, from what their dashboards show, and from the rows behind a table on one of those pages. It can set up an alert or an email for them on those same numbers, and look things up on the web when your company has that switched on. A new chat starts them on what is shared with them: what changed on their dashboards this week, or a warning when a number they can see drops. While nothing is shared with their group, it says so.

It has no SQL, no tables and no files, so it cannot look anything else up, and it never works a number out another way. Asked for something outside the group ("What is Rachel's salary?"), it says it can't see that, and the answer always ends on a line the app writes: what they can ask about instead and that an admin can share more, with what was not shared when the chat tried to look it up. A table or a chart in their answers can be emailed to them; a file of its rows is not theirs, and a request for one is answered with the same line. Under an answer they can say Right or Wrong; sending one to a teammate to check is for the people who build. Their conversations are their own; only admins read everyone's, in Settings, Activity.

Agents' keys and dashboards

An agent's key is not a person and is in no group. It sees a dashboard only when it can read every dataset the page's numbers and saved queries come from; a page that asks for nothing yet is its maker's and an admin's until it does. Changing one (renaming it, moving it, building or publishing it) takes that and a key that can write somewhere; deleting one takes that, or an admin. A saved query is listed and read only by a key that can read its tables, and a name already taken by one a key cannot read is not its to save over.

A page's picture in the Library shows the figures as they are, so a key that sees the data masked does not get it, and a page opened with such a key, or with one that cannot build, is never pictured from what it shows them. A draft's code and picture are for whoever may build; anyone else sees the published version.

Where it runs

Each dashboard page runs in a sealed frame with no network of its own. Data reaches it only through the app, as the signed-in person, so a page can never send SQL or leak what it shows. The company theme (colours, fonts) is set once and every dashboard inherits it.

A page that sets no background of its own sits on the app's own, as part of the app: dark slate in the dark appearance, cream in the light one, and it changes with the appearance while it is open. A page built in its own colours, or in a company theme that sets a background, keeps them, on a sheet of its own.

What to say to it

A sales dashboard by product and region, refreshed each morning.
Add gross sales, returns and net revenue as separate numbers.
Which definition is this number using?

All docs · Something wrong on this page? Tell us.