How to build ShipStation shipping dashboards in Metabase
ShipStation is shipping and order-fulfillment software that pulls orders from every sales channel you sell on, batches label creation across carriers, and tracks shipments through to delivery. Metabase is where you turn that data into shared, trustworthy dashboards. This guide covers two complementary paths: a lightweight MCP + CLI route that pulls live data with the ShipStation API MCP Server and loads a CSV into Metabase with the Metabase CLI, and a durable pipeline route that lands ShipStation data in a database so you can build dashboards anyone can read.
How do you connect ShipStation to Metabase?
Most teams combine both routes: quick answers through MCP and CLI uploads first, then recurring reporting on a warehouse-backed model.
Live answers in, quick analysis out
Pair the ShipStation API MCP Server with the Metabase CLI. Use MCP for live lookups, write a scoped result to CSV, then load it into Metabase as a ready-to-query table and model.
- Quick questions such as "show me fulfillment cost by channel and warehouse"
- Loading ShipStation 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 ShipStation data in a database or warehouse — via connector, scheduled API pulls, or a direct database connection — then point Metabase at it.
- ShipStation 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 fulfillment cost by channel and warehouse and shipping cost per order over time
- 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 ShipStation data in Metabase?
Each of these is built from shipments joined to the related orders from connected sales channels, carriers and service levels, warehouses and stores data your sync exposes:
- Fulfillment cost by channel and warehouse
- Shipping cost per order over time
- Carrier and service-level mix
- Order-to-ship time and SLA compliance
- Late shipments and delivery exceptions
Which ShipStation dashboards should you build in Metabase?
Shipping spend
What fulfillment costs to move.
- Total label spend by month (line)
- Shipping cost per order (number + trend)
- Shipping cost as a share of order value (line)
- Spend by carrier and service level (stacked bar)
Cost drivers
Where the money leaks.
- Cost by zone and weight band (heat table)
- Carrier adjustments and reweighs (table)
- Voided and refunded labels (number + trend)
- Average billed vs. quoted cost gap (line)
Delivery performance
Whether promises are kept.
- On-time delivery rate with tracking coverage shown (number + trend)
- Transit time p50 and p90 by carrier (line)
- Late deliveries by zone (bar)
- Time from order to first carrier scan (line)
Rate strategy
What to change next quarter.
- Cost per order by carrier, trended (line)
- Service-level mix over time (stacked area)
- Shipping revenue collected vs. cost paid (combo)
- Top routes by spend (table)
How do you use the ShipStation API MCP Server with the Metabase CLI?
Pair the ShipStation API MCP Server with the Metabase CLI for fast, hands-on analysis. MCP is useful for scoped lookups and summarized exports; the Metabase CLI's upload command loads CSV data into Metabase and creates a ready-to-query table and model.
Example workflow
- Ask the MCP server for the last 90 days of shipments, one row per label with carrier, service level, billed cost, and zone.
- 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
- MCP lookups 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. - Cost trends need labels across complete months, and carrier adjustments post days after purchase — late-arriving rows will restate recent periods.
mb upload csvneeds an uploads database configured under Admin → Settings → Uploads.
How do you set up ShipStation MCP and the Metabase CLI?
ShipStation API MCP Serverofficial
- Transport
- Local stdio server, run from source (Node or Docker)
- Auth
- ShipStation API key (SHIPSTATION_API_KEY)
- Best for
- Live order, shipment, and rate lookups
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)
{
"mcpServers": {
"shipstation": {
"command": "node",
"args": ["/path/to/mcp-shipstation-api/build/index.js"],
"env": {
"SHIPSTATION_API_KEY": "your-v2-api-key"
}
}
}
}Set expectations here: ShipStation's server lives in the vendor's own GitHub org and targets the current V2 API, but it self-describes as an MVP, isn't published to npm, and hasn't seen a commit since August 2025 — you clone and build it. A separate, actively maintained documentation server at https://docs.shipstation.com/mcp (no auth) answers questions about the API itself. Third-party packages with ShipStation in the name exist and are not vendor-maintained; only shipstation/mcp-shipstation-api is.
# 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 shipments export — creates a table AND a model
mb upload csv --file shipstation-shipments.csv --collection root
# Refresh that same table later from a new export
mb upload replace <table-id> --file shipstation-shipments.csvCan you generate a ShipStation dashboard with AI?
Yes. Use the prompt below with any assistant that can run the ShipStation API MCP Server and the Metabase CLI. It works end to end: if ShipStation 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 ShipStation shipping & delivery analytics.
Work end to end: get the data into Metabase if it isn't there yet, then build.
Goal: Help the team understand label spend, shipping cost per order, carrier and zone cost drivers, and on-time delivery from ShipStation data.
Step 1 — Find or load the data:
- First, check what already exists in Metabase (search for shipstation tables and
models). If durable ShipStation 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 with the ShipStation API MCP Server:
shipments, plus orders from connected sales channels, carriers and service levels, warehouses and stores.
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
ShipStation — 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.
- Cost trends need labels across complete months, and carrier adjustments post days after purchase — late-arriving rows will restate recent periods.
- If a metric can't be computed from the data present, say so on the card
instead of approximating it.
Dashboard title: ShipStation Shipping & Delivery Overview
Sections:
1. Executive summary: Label spend this month; Cost per order;
Cost as % of order value; On-time delivery rate; Tracking coverage.
2. Spend: Spend by month; by carrier and service level; voided labels.
3. Cost drivers: Cost by zone and weight band; carrier adjustments.
4. Delivery: On-time rate; transit p50/p90 by carrier; late by zone.
5. Strategy: Cost per order by carrier; service mix; revenue vs. cost.
Filters: Date range, Store or channel, Carrier, Warehouse, Service.
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 ShipStation data into a database or warehouse?
For dashboards that need history and reliability, land ShipStation 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 ShipStation API v2 for control over grain, fields, and refresh cadence.
- MCP + CSV — use this for quick exploration and one-off slices.
Fivetran ships an official managed ShipStation connector (Lite type, generally available) — the lowest-effort durable path. Airbyte's community source covers 11 streams including orders, shipments, fulfillments, and stores, but it authenticates with an API key <em>and</em> secret, which means it is built on the deprecated V1 API; weigh that migration risk before standardizing on it. Custom pulls against V2 give you the most control, at 200 requests per minute by default.
Notes
- Decide the grain first (one row per shipment, rolled up to order and to day for trend cards) — it drives every trend card.
- Land raw tables first, then build clean Metabase models on top.
- Normalize label-date, order-id, carrier, service-level, billed-cost, zone, weight, and void-status fields.
How should you model ShipStation data in Metabase?
Core tables
| Table | Grain | Key columns |
|---|---|---|
shipping_labels | one row per shipment/label | shipment_id, created_at, order_id, store_id, warehouse_id, carrier, service_level, shipment_cost, insurance_cost, currency, void_status, tracking_number |
shipment_tracking | one row per shipment, latest tracking outcome | tracking_number, carrier, shipped_at, eta_at_purchase, delivered_at, tracking_status, days_in_transit |
orders | one row per order pulled from a sales channel | order_id, store_id, ordered_at, paid_at, order_total, shipping_paid, items_count, destination_country |
Modeling advice
- Build a clean
shipping_labelsmodel 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.
- Keep
store_idon every shipment — fulfillment cost per channel is the question ShipStation data answers better than anything else in the stack. - Model order-to-ship time from
orders.paid_attoshipping_labels.created_at; it isolates warehouse lag from carrier transit time. - Store insurance and other surcharges as separate columns from base shipment cost so rate negotiations use the right number.
- Store amounts in minor units or with an explicit currency column, and convert once in the model layer rather than per card.
Which ShipStation metrics should you track in Metabase?
| Metric | Definition | Notes |
|---|---|---|
| Shipping cost per order | Billed shipment cost per order, split by channel and warehouse. | Exclude voided labels; roll multi-package orders up first. |
| On-time delivery rate | Shipments delivered by the promised date over those with a known outcome. | Separate warehouse lag from carrier lateness. |
| Average order value | Order value by channel — the denominator for shipping cost ratios. | Channel mix moves this more than pricing does. |
| Gross margin | Margin after product cost, fees, and fulfillment. | Shipping charged to the customer rarely covers shipping paid. |
What SQL powers ShipStation dashboards in Metabase?
These assume a cleaned analytical model in a warehouse (PostgreSQL dialect). Adjust table and column names to match your pipeline.
What each channel charges for shipping versus what it actually costs to ship.
SELECT
o.store_id,
date_trunc('month', o.ordered_at)::date AS month,
COUNT(DISTINCT o.order_id) AS orders,
ROUND(SUM(l.shipment_cost + l.insurance_cost), 2) AS shipping_paid,
ROUND(SUM(o.shipping_paid), 2) AS shipping_collected,
-- Recovery above 100% means shipping is a profit center, not a leak.
ROUND(
100.0 * SUM(o.shipping_paid)
/ NULLIF(SUM(l.shipment_cost + l.insurance_cost), 0), 1
) AS recovery_pct
FROM orders o
JOIN shipping_labels l
ON l.order_id = o.order_id
AND l.void_status IS DISTINCT FROM 'voided'
GROUP BY o.store_id, month
ORDER BY month DESC, shipping_paid DESC;Warehouse performance, isolated from anything the carrier does.
SELECT
l.warehouse_id,
date_trunc('week', o.paid_at)::date AS week,
COUNT(*) AS shipments,
ROUND(
PERCENTILE_CONT(0.5) WITHIN GROUP (
ORDER BY EXTRACT(EPOCH FROM (l.created_at - o.paid_at)) / 3600
)::numeric, 1
) AS median_hours_to_ship,
ROUND(
PERCENTILE_CONT(0.9) WITHIN GROUP (
ORDER BY EXTRACT(EPOCH FROM (l.created_at - o.paid_at)) / 3600
)::numeric, 1
) AS p90_hours_to_ship
FROM orders o
JOIN shipping_labels l ON l.order_id = o.order_id
WHERE o.paid_at >= CURRENT_DATE - INTERVAL '90 days'
GROUP BY l.warehouse_id, week
ORDER BY week DESC, p90_hours_to_ship DESC;Where the shipping budget goes, and how the mix shifts.
WITH monthly AS (
SELECT
date_trunc('month', created_at)::date AS month,
carrier,
service_level,
SUM(shipment_cost) AS spend
FROM shipping_labels
WHERE void_status IS DISTINCT FROM 'voided'
GROUP BY 1, 2, 3
)
SELECT
month,
carrier,
service_level,
ROUND(spend, 2) AS spend,
ROUND(
100.0 * spend / NULLIF(SUM(spend) OVER (PARTITION BY month), 0), 1
) AS share_of_month_pct
FROM monthly
ORDER BY month DESC, spend DESC;What are common mistakes when analyzing ShipStation in Metabase?
Related
Related analytics
Related dashboards
Related integrations
FAQ
Does Metabase connect natively to ShipStation?
Should Metabase replace ShipStation's built-in reports?
Which ShipStation API version should a new pipeline use?
https://api.shipstation.com/v2 with an API-Key header. V1 (ssapi.shipstation.com, key plus secret) still works but is deprecated and slated for removal. The vendor's own MCP server targets V2; some third-party connectors still use V1.