How to build Toast sales dashboards in Metabase
Toast is the restaurant platform that runs point of sale, online ordering, kitchen display, payroll, and payments for tens of thousands of restaurants — and records every check, item, discount, and tender along the way. 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 Toast Orders API and loads a CSV into Metabase with the Metabase CLI, and a durable pipeline route that lands Toast data in a database so you can build dashboards anyone can read.
How do you connect Toast to Metabase?
Most teams combine both routes: quick answers through API exports and CLI uploads first, then recurring reporting on a warehouse-backed model.
One correction worth making up front: Toast API access is no longer partner-only. Restaurants on an RMS Essentials or higher subscription can self-generate read-only credentials from the Toast Partner Integrations page in Toast Web, given an active employee account with the Manage Integrations permission. Self-serve access is read-only by design — every granted scope ends in :read — which suits analytics exactly.
Live answers in, quick analysis out
Script a scoped export against the Toast Orders API, write the result to CSV, then load it into Metabase as a ready-to-query table and model.
- Quick questions such as "show me net sales by location and business date"
- Loading Toast exports into Metabase in seconds
- Spot-checks and one-off investigations without pipeline work
- 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
Durable dashboards with history
Land Toast data in a database or warehouse — via connector, scheduled API pulls, or a direct database connection — then point Metabase at it.
- Toast 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 net sales by location and business date and average check size by daypart
- 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 Toast data in Metabase?
Each of these is built from checks joined to the related check items (selections) and modifiers, discounts, comps, and voids, payments and tender types data your export exposes:
- Net sales by location and business date
- Average check size by daypart
- Menu mix and top-selling items
- Discounts, comps, and void rate
- Labor cost as a share of sales
Which Toast dashboards should you build in Metabase?
Sales
The day-to-day trading picture.
- Net sales by location by day (line)
- Average check size (number + trend)
- Checks by daypart (bar)
- Sales this week vs. the same week last year (combo)
Item mix
What sells, and what earns.
- Top items by revenue and by units (table)
- Category mix over time (stacked area)
- Attach rate for add-ons and modifiers (number)
- Items with falling sales week over week (table)
Discounts and voids
The margin that quietly disappears.
- Discounts and comps as a share of gross sales (line)
- Void rate by location and employee (table)
- Comps by reason code (bar)
- Refunds after close (table)
Tenders and settlement
How money arrives and what it costs.
- Payment method mix (stacked bar)
- Effective processing fee rate (line)
- Tips by location and daypart (bar)
- Deposits received vs. net sales recorded (combo)
How do you use the Toast Orders API with the Metabase CLI?
Pair the Toast Orders 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 last month's checks summarized by day, location, and daypart — not raw check lines.
- Export the result as CSV, keeping stable IDs, dates, currency codes, and the fee breakdown intact.
- Run
mb upload csvto 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 replaceor move to the pipeline for real history. - Sales trends need complete business days; late-closed checks and end-of-day adjustments mean the last day or two keeps moving.
mb upload csvneeds an uploads database configured under Admin → Settings → Uploads.
How do you set up the Toast API and the Metabase CLI?
Toast Orders APIno vendor MCP
- Transport
- REST over HTTPS (ws-api.toasttab.com)
- Auth
- Machine client credentials + Toast-Restaurant-External-ID header
- Best for
- Scripted daily order and labor 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)
# 1. Exchange machine-client credentials for a bearer token
TOKEN=$(curl -s -X POST \
https://ws-api.toasttab.com/authentication/v1/authentication/login \
-H 'Content-Type: application/json' \
-d '{"clientId":"'"$TOAST_CLIENT_ID"'",
"clientSecret":"'"$TOAST_CLIENT_SECRET"'",
"userAccessType":"TOAST_MACHINE_CLIENT"}' \
| jq -r '.token.accessToken')
# 2. Pull yesterday's orders for one restaurant (paged, 5 req/s cap)
curl -s -G https://ws-api.toasttab.com/orders/v2/ordersBulk \
-H "Authorization: Bearer $TOKEN" \
-H "Toast-Restaurant-External-ID: $TOAST_RESTAURANT_GUID" \
--data-urlencode "startDate=$(date -u -v-1d +%Y-%m-%dT00:00:00.000Z)" \
--data-urlencode "endDate=$(date -u +%Y-%m-%dT00:00:00.000Z)" \
--data-urlencode "pageSize=100" \
> toast-orders.json
# 3. Flatten orders -> checks -> selections into a CSV for upload
jq -r '.[] | .checks[]? | [
.guid, .openedDate, .closedDate, .amount, .totalAmount,
(.appliedDiscounts | map(.discountAmount) | add // 0),
(.voided | tostring)
] | @csv' toast-orders.json > toast-pos-checks.csvThere is no official Toast MCP server (verified July 2026) — the community servers you'll find are not vendor-affiliated, and one popular result named “toast-mcp” is a Windows desktop notification server with no connection to Toast POS at all. The honest route is the documented REST API above, which an AI assistant can script for you. If Toast ships an MCP server later, only route 1 changes: the same CSV lands in Metabase the same way.
# 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 checks export — creates a table AND a model
mb upload csv --file toast-checks.csv --collection root
# Refresh that same table later from a new export
mb upload replace <table-id> --file toast-checks.csvCan you generate a Toast 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 Toast 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.
Create a polished Metabase dashboard for Toast pos sales analytics.
Work end to end: get the data into Metabase if it isn't there yet, then build.
Goal: Help the team understand net sales by location, average check, item mix, discounts and voids, and tender mix from Toast data.
Step 1 — Find or load the data:
- First, check what already exists in Metabase (search for toast tables and
models). If durable Toast 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 Toast Orders API:
checks, plus check items (selections) and modifiers, discounts, comps, and voids, payments and tender types.
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
Toast — 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.
- Sales trends need complete business days; late-closed checks and end-of-day adjustments mean the last day or two keeps moving.
- If a metric can't be computed from the data present, say so on the card
instead of approximating it.
Dashboard title: Toast POS Sales Overview
Sections:
1. Executive summary: Net sales; Average check; Checks; Discount rate;
Void rate.
2. Sales: Net sales by location and day; checks by daypart; year-over-year.
3. Menu: Top items by revenue and units; category mix; modifier attach rate.
4. Leakage: Discounts and comps; voids by location; refunds after close.
5. Settlement: Tender mix; processing fee rate; tips; deposits vs. sales.
Filters: Date range, Location, Daypart, Dining option, Revenue center, Employee.
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 Toast data into a database or warehouse?
For dashboards that need history and reliability, land Toast 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 Toast Orders API for control over grain, fields, and refresh cadence.
- API + CSV — use this for quick exploration and one-off slices.
There is no managed Toast connector on Airbyte or Fivetran. Fivetran publishes a Connector SDK <em>template</em> for Toast — real, but you build and deploy it yourself, which makes it a starting point rather than a turnkey sync. Most teams schedule nightly <code>ordersBulk</code> pulls per location and flatten to check and item tables. Respect the limits: 20 requests per second and 10,000 per 15 minutes across all Toast APIs combined, with <code>ordersBulk</code> capped at 5 requests per second per location.
Notes
- Decide the grain first (one row per check and one per check item, both stamped with business date and location) — it drives every trend card.
- Land raw tables first, then build clean Metabase models on top.
- Normalize business-date, location, daypart, check-id, net-sales, discounts, voids, and tender-type fields.
How should you model Toast data in Metabase?
Core tables
| Table | Grain | Key columns |
|---|---|---|
pos_checks | one row per check | check_guid, order_guid, location_id, business_date, opened_at, closed_at, dining_option, gross_sales, discount_amount, net_sales, tax_amount, tip_amount, is_voided |
pos_check_items | one row per selection (line item) on a check | selection_guid, check_guid, business_date, menu_item_guid, item_name, category, quantity, unit_price, discount_amount, net_amount, is_voided |
pos_locations | one row per restaurant location | location_id, restaurant_guid, name, timezone, opened_on, region |
Modeling advice
- Build a clean
pos_checksmodel 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.
- Use Toast's
businessDate, not the calendar date of the timestamp — a check closed at 1:30am belongs to the previous trading day, and mixing the two makes every weekend comparison wrong. - Model voids and comps as distinct concepts: a void removes a check or item that was never sold, a comp is a real sale given away. Netting them together hides both the loss-prevention signal and the hospitality cost.
- Keep
dining_option(dine-in, takeout, delivery) on every check — third-party delivery orders carry different ticket sizes and commissions, and blending them distorts average check. - Store amounts in minor units or with an explicit currency column, and convert once in the model layer rather than per card.
Which Toast metrics should you track in Metabase?
| Metric | Definition | Notes |
|---|---|---|
| Average check size | Net sales per non-voided check, by daypart and dining option. | Decide once whether tax and tips are in the number. |
| Platform fee rate | Processing and marketplace commission as a share of gross sales. | Delivery marketplace commission dwarfs card processing. |
| Gross margin | Sales less food cost, where recipe or inventory data exists. | Needs item-level cost data Toast alone won't give you. |
| Repeat purchase rate | Share of guests who return, where loyalty identifies them. | Anonymous cash checks can't be attributed — state coverage. |
What SQL powers Toast dashboards in Metabase?
These assume a cleaned analytical model in a warehouse (PostgreSQL dialect). Adjust table and column names to match your pipeline.
The core trading view, on business date, with voids excluded.
WITH local_checks AS (
SELECT
c.business_date,
c.net_sales,
-- Daypart is a wall-clock idea, so read the hour in the venue's
-- local time. Toast timestamps are UTC; convert with the location
-- timezone before extracting the hour (skip if already local).
EXTRACT(
HOUR FROM (c.opened_at AT TIME ZONE 'UTC' AT TIME ZONE l.timezone)
) AS local_hour
FROM pos_checks c
JOIN pos_locations l ON l.location_id = c.location_id
WHERE c.is_voided = false
AND c.business_date >= CURRENT_DATE - INTERVAL '30 days'
)
SELECT
business_date,
-- Late night covers 22:00–04:59 so a post-midnight close counts as
-- late night, not breakfast.
CASE
WHEN local_hour BETWEEN 5 AND 10 THEN 'breakfast'
WHEN local_hour BETWEEN 11 AND 15 THEN 'lunch'
WHEN local_hour BETWEEN 16 AND 21 THEN 'dinner'
ELSE 'late night'
END AS daypart,
COUNT(*) AS checks,
ROUND(SUM(net_sales), 2) AS net_sales,
ROUND(AVG(net_sales), 2) AS avg_check,
ROUND(
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY net_sales)::numeric, 2
) AS median_check
FROM local_checks
GROUP BY business_date, daypart
ORDER BY business_date DESC, daypart;Which items carry the menu, and which are quietly fading.
WITH weekly AS (
SELECT
date_trunc('week', business_date)::date AS week,
item_name,
category,
SUM(quantity) AS units,
SUM(net_amount) AS revenue
FROM pos_check_items
WHERE is_voided = false
GROUP BY 1, 2, 3
)
SELECT
week,
item_name,
category,
units,
ROUND(revenue, 2) AS revenue,
ROUND(
100.0 * (units - LAG(units) OVER (
PARTITION BY item_name ORDER BY week
)) / NULLIF(LAG(units) OVER (
PARTITION BY item_name ORDER BY week
), 0), 1
) AS units_wow_pct
FROM weekly
ORDER BY week DESC, revenue DESC;Three different leaks, kept separate so each has an owner.
SELECT
l.name AS location,
date_trunc('month', c.business_date)::date AS month,
ROUND(
100.0 * SUM(c.discount_amount)
/ NULLIF(SUM(c.gross_sales), 0), 2
) AS discount_rate_pct,
ROUND(
100.0 * COUNT(*) FILTER (WHERE c.is_voided)
/ NULLIF(COUNT(*), 0), 2
) AS void_rate_pct,
ROUND(SUM(c.gross_sales) FILTER (WHERE c.is_voided), 2) AS voided_value
FROM pos_checks c
JOIN pos_locations l ON l.location_id = c.location_id
GROUP BY l.name, month
ORDER BY month DESC, discount_rate_pct DESC;What are common mistakes when analyzing Toast in Metabase?
Related
Related analytics
Related dashboards
Related integrations
FAQ
Does Metabase connect natively to Toast?
Should Metabase replace Toast's built-in reports?
Do I need to be a Toast partner to get API access?
:read, which is exactly what analytics needs. Note that self-serve Standard API access is US-only at present.Is there a Toast MCP server?
How do I sync Toast data on a schedule?
ordersBulk pulls per location and flatten them into check and item tables. Keep within the limits — 20 requests per second globally, and 5 per second per location on ordersBulk. The restaurant sales dashboard lists what to build once the data lands.