Skip to main content
Run a measures-and-dimensions query against your event stream. Wraps POST /api/query — see the API reference.

Usage

upstack query \
  --measures orders.gross_revenue,tracked.purchases \
  --dimensions utm_source \
  --date-start 2026-04-01 \
  --date-end 2026-04-30

Required flags

FlagDescription
--measures <m1,m2,...>Comma-separated canonical measure ids (see upstack measures).
--granularity <g>none, second, minute, hour, day, week, month, quarter, or year.
--date-start <YYYY-MM-DD> --date-end <YYYY-MM-DD>Date range.

Optional flags

FlagDescriptionDefault
--dimensions <d1,d2,...>Comma-separated dimension ids. Max 5.
--filter <json>Canonical Filter as JSON. See the Filters section below for the shape.
--compare-start <YYYY-MM-DD> --compare-end <YYYY-MM-DD>Optional comparison period. Must not overlap the primary date range.
--timezone <tz>IANA timezone (e.g. America/New_York).UTC

Shared flags

All query commands (query, query-attribution, query-cohort) support these:
FlagDescriptionDefault
-i, --interactiveBuild the query step-by-step with prompts.
--output <format>json, table, or csv.json
--file <path>Write output to a file instead of stdout.
--from-file <path>Load query parameters from a JSON file. CLI flags override file values.

Examples

# Gross revenue by day, last 30 days
upstack query --measures orders.gross_revenue --granularity day \
  --date-start 2026-04-01 --date-end 2026-04-30

# CSV output, broken down by UTM source
upstack query --measures orders.gross_revenue,tracked.purchases \
  --dimensions utm_source --granularity day \
  --date-start 2026-04-01 --date-end 2026-04-30 \
  --output csv --file ./april-by-source.csv

# Scope to web/POS orders for new customers via canonical filter
upstack query --measures orders.gross_revenue --granularity day \
  --date-start 2026-04-01 --date-end 2026-04-30 \
  --filter '{"and":[{"field":"orders.source_name","op":"in","value":["web","pos"]},{"field":"orders.customer_type","op":"equals","value":"new_customer"}]}'

# Interactive
upstack query -i

Filters

--filter takes a canonical Filter JSON object. The shape is a recursive { and | or | not } group tree with leaves of the form { field, op, value }:
{
  "and": [
    { "field": "orders.source_name", "op": "in", "value": ["web", "pos"] },
    { "field": "orders.customer_type", "op": "equals", "value": "new_customer" }
  ]
}
Field ids are namespaced (orders.*, channel.*, attribution.*, emq.*) and each one is only valid in certain contexts. Run upstack filters --detail to list every field with its operators and applicable contexts before constructing a filter.

Save a query for reuse

upstack saved create morning-report --command query --from-file ./params.json
upstack saved run morning-report
See upstack saved for the full reference.