How to query

What a query names (metrics, dimensions, filters, order, a row limit), the names it takes, time, filters, how to read the answer and access.

ℹ️

Private preview

Composable dashboards and the metrics API are in private preview: available to invited accounts, and features may change. See Integration and feature lifecycles for what this means, and reach out to your account representative to request access.

🤖

Using an agent? It writes the queries for you. This page is for agents and for anyone querying the metrics API directly.

A query

A query asks for one or more metrics, grouped by dimensions, with filters. The pages of Composable dashboards describe every example query this way. This one counts alerts per week over the last 3 months:

  • Metrics: incident_count
  • Grouped by: metric_time__week
  • Filter: metric_time__day on or after 3 months ago
PartWhat it takes
MetricsOne or more metric names from the Metrics pages, such as incident_count. Each is a column of the answer.
Grouped byDimension names, such as monitor__monitor_type. Each is a column of the answer. Grouping by asset or monitor itself returns one row per table or monitor.
FilterA condition every row must meet: a dimension is, or is not, one of some values; a date is on or after, or on or before, a date; a number is at least, or at most, a value.
Sorted byColumns to sort by, highest or lowest first.
At most N rowsThe most rows to return: 1,000 unless you ask for more, at most 10,000. The answer says when there were more.

The answer has a column per metric and dimension, the rows, and how current the data is. Read columns by name, not by position; a dimension can come back under a longer name, such as asset__warehouse__warehouse_name for warehouse__warehouse_name grouped with asset.

Send a query

The metrics API has two calls, both authenticated with a Monte Carlo API key in the header Authorization: Bearer <key id>:<key secret>:

  • GET https://api.getmontecarlo.com/api/v2/metrics/catalog lists the metrics and the dimensions each one groups by.
  • POST https://api.getmontecarlo.com/api/v2/metrics/query runs a query, sent as JSON.

A query in words maps to the JSON like this:

In wordsIn the JSON
Metrics: a, b"metrics": ["a", "b"]
Grouped by: x, y"group_by": ["x", "y"]
Filter: f is v, or is one of v, w{"field": "f", "op": "in", "values": ["v", "w"]} in "filters"
Filter: f is not v, or is none of v, w{"field": "f", "op": "not_in", "values": ["v", "w"]}
Filter: f on or after, or at least, v{"field": "f", "op": "gte", "values": ["v"]}
Filter: f on or before, or at most, v{"field": "f", "op": "lte", "values": ["v"]}
Sorted by: m, highest first (lowest first)"order_by": [{"field": "m", "descending": true}] (false)
At most N rows"limit": N

true and false are JSON booleans; other values are strings. A date such as "30 days ago" is sent as the date, YYYY-MM-DD. The example questions on the Metrics pages show each query in words and as JSON.

curl -s -X POST https://api.getmontecarlo.com/api/v2/metrics/query \
  -H "Authorization: Bearer $MCD_ID:$MCD_TOKEN" -H 'Content-Type: application/json' \
  -d '{"metrics": ["coverage_rate", "covered_assets", "population_assets"]}'

The answer is JSON: columns (the dimensions, then the metrics), rows, data_as_of (how current the data is) and truncated (true when there were more rows than the limit). An account can send up to 10 queries per second; above that the API answers 429: wait a second and send the query again.

Names

  • Metric names are unique, for example coverage_rate.
  • Dimension names start with what they describe: monitor__monitor_type, domain__domain_name. The Dimensions pages list them.
  • Not every dimension works with every metric. Each metric's row says which dimensions it groups by; a query with another dimension is refused with a message that lists the dimensions that work. To combine two groupings, take two steps, as Before you group or filter shows.
  • To split a metric by domain, data product, asset tag, monitor domain, monitor tag or audience, use its per-grouping metric, such as domain_coverage_rate. Members overlap, and tables, monitors or alerts that belong to no member are in no row, so their numbers do not add up to the account's: see Totals across members in Before you group or filter. The account's number comes from the metric without the grouping, such as coverage_rate.

Time

  • metric_time is each metric's own date: when an alert was created, when an event was detected, the day credits were consumed. Group by it at a grain: metric_time__day, metric_time__week or metric_time__month.
  • Filter dates are dates (YYYY-MM-DD), not expressions such as "last 30 days": compute the date first. The examples on these pages say "30 days ago" for the date 30 days before today.
  • Periods ("this quarter", "last month") and how far back a daily, weekly or monthly series goes: Time in the Glossary.
  • Some metrics are current state, not a series: coverage, monitor counts and asset health. Do not group them by metric_time.
  • A series starts where the stored history starts. Asking for earlier dates returns the rows from that start, without an error: check the first row's date.

Filters

A filter keeps the rows where a dimension has the values you name. A query can have several filters, and a row has to pass all of them. The pages write a filter in words:

Filter in wordsKeeps the rows where the dimension
is a, is one of a, bhas one of the values
is not a, is none of a, bhas none of the values
on or after a date, at least a numberis that value or later or higher
on or before a date, at most a numberis that value or earlier or lower

For example, the number of monitors per monitor type, without deleted monitors and without validation monitors:

  • Metrics: monitor_count
  • Grouped by: monitor__monitor_type
  • Filter: monitor__is_monitor_deleted is false
  • Filter: monitor__monitor_type is not validation

Values are strings, numbers or true / false. Values of a dimension are your own, such as your domain names; the dimension's description tells what they mean.

  • Filter on a dimension, never on a metric. To keep only monitors with a breach, group by monitor and read the metric.
  • To filter on a list of tables or monitors, use asset__asset_mcon or monitor__monitor_uuid. asset and monitor are for grouping only.
  • A row with an empty value passes neither "is" nor "is not": "is none of a, b" leaves out the empty rows too. To see the empty group, group by the dimension and read its empty row.
  • "At least" and "at most" include the value itself. A filter matches whole values: to find values by part of a name (every domain with "finance" in it), list the dimension's values first, with a count grouped by the dimension, and filter on the ones you need.

The answer

  • No rows means nothing matched. A filter value that does not exist also gives no rows, so list the dimension's values to tell the two apart.
  • A member with nothing in the period has no row, not a row with 0.
  • An empty value in a dimension column is a group of its own, such as monitors without a data quality dimension or alerts without a severity, never a total.
  • A request grouped by several dimensions has no total rows: a member's total comes from the same metric grouped by the member alone.
  • A total or a headline number comes from a request without the grouping. Rows of overlapping members, and rows of a breakdown by several dimensions, do not add up to it.
  • An answer marked truncated holds only the first rows: say so, and never estimate the rest.
  • A request grouped by asset includes AI agents and other assets that are not tables; for tables only, filter asset__asset_category is table.
  • A request grouped by asset or monitor can return thousands of rows. Ask only for the columns you show, and for a top N with "Sorted by" and "At most N rows".

Access

  • Every query is scoped to your account.
  • If your access is limited to some domains, queries are limited to them too. Metrics that cannot be split by domain are refused with a message that points to their per-domain metrics: metrics not tied to a domain are only available to users with access to all domains.

Did this page help you?