curl --request POST \
--url https://api.select.dev/v2/metrics/snowflake-workloads/query \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'x-tenant-id: <x-tenant-id>' \
--data '
{
"measures": [
"sum_spend"
],
"dimensions": [
"snowflake_account_name",
"warehouse_name"
],
"filter_expression": {
"operator": "and",
"filters": [
{
"field": "day",
"operator": "in range",
"value": "30D"
},
{
"field": "warehouse_name",
"operator": "is not"
},
{
"field": "warehouse_name",
"operator": "startswith",
"value": "COMPUTE_SERVICE_WH_",
"not": true
}
]
},
"sort": [
{
"field": "sum_spend",
"direction": "desc"
}
],
"limit": 10
}
'{
"items": [
{}
],
"page_token": "<string>",
"row_count": 123,
"sql": "<string>"
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}Query Snowflake workloads
One row per group of Snowflake workload activity — the named units of work that run on a warehouse, such as dbt models, query patterns, tasks, stored procedures and BI-tool queries. Measures cover cost, credits, runtime, queueing and row throughput. Activity is grouped to the hour it ran in for a request that asks about hours, and to the day otherwise.
Returns one row per combination of the requested dimensions, carrying the requested measures. Each row is keyed by dimension and measure name. row_count is the number of rows in items: results are not paginated, so an aggregation with more rows than limit is cut short at limit rather than continued under a page_token. Send X-Team-Id to evaluate the query as a team you belong to; rows are then limited to what that team’s roles reach.
Use this route to compare spend across every kind of Snowflake workload in one table: warehouse spend, the top workloads of any type, and spend by workload type. The table holds all attributed Snowflake spend, including storage, serverless features, AI services and idle warehouse time. sum_spend is the cost in dollars. sum_spend_annualized is a run-rate, not spend in the period. resource_type names the workload type. Its values are lowercase keys (query_pattern, dbt, task, stored_procedure, dynamic_table, looker, mode, hex, periscope, sigma, fivetran, custom, snowpipe, snowpipe_streaming, automatic_clustering, search_optimization, storage, idle_warehouse) and Title Case AI names (Cortex Analyst, Cortex Agent, Snowflake Intelligence, and others). The SELECT app’s All Workloads page applies resource_type != "storage".
For the fields of one workload type, use its route: snowflake-dbt, snowflake-tasks, snowflake-stored-procedures, snowflake-dynamic-tables, snowflake-looker, snowflake-mode, snowflake-hex, snowflake-sigma, snowflake-periscope, snowflake-fivetran, snowflake-custom-workloads, snowflake-serverless or snowflake-storage. For per-query detail, use snowflake-query-patterns or snowflake-queries. A request that names hour, start_hour, start_hour_of_day, start_hours_of_day, workload_type or a table-footprint measure (count_distinct_*, *_first_25) reads the hourly table. All other requests read the daily table.
curl --request POST \
--url https://api.select.dev/v2/metrics/snowflake-workloads/query \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'x-tenant-id: <x-tenant-id>' \
--data '
{
"measures": [
"sum_spend"
],
"dimensions": [
"snowflake_account_name",
"warehouse_name"
],
"filter_expression": {
"operator": "and",
"filters": [
{
"field": "day",
"operator": "in range",
"value": "30D"
},
{
"field": "warehouse_name",
"operator": "is not"
},
{
"field": "warehouse_name",
"operator": "startswith",
"value": "COMPUTE_SERVICE_WH_",
"not": true
}
]
},
"sort": [
{
"field": "sum_spend",
"direction": "desc"
}
],
"limit": 10
}
'{
"items": [
{}
],
"page_token": "<string>",
"row_count": 123,
"sql": "<string>"
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}Authorizations
Organization API key (sl_…).
Headers
Act as this team: rows are limited to what the team's roles reach instead of the caller's own. The caller must be a member of the team or hold the organization-wide permission the route requires.
The organization ID the request is scoped to.
Body
Aggregate Snowflake workload activity over a period.
Rows are already scoped to the accounts and usage groups the caller may see.
Activity is stored twice, rolled up to the day and to the hour, and the
hourly table carries every field the daily one does plus the fields that only
mean something within a day: hour, start_hour, start_hour_of_day,
start_hours_of_day, workload_type and the table-footprint measures. A
request naming any of those reads the hourly table; anything else reads the
cheaper daily rollup.
The date the new_in_period dimension measures from. Omit to take it from the earliest date the query's own filters allow.
Categorize against these set definitions instead of the organization's saved usage group sets, for evaluating a set before saving it. Omit to use the saved sets, which is what every other surface reports against.
Show child attributes
Show child attributes
Aggregates to compute over the matching rows.
Show child attributes
Show child attributes
Columns to group the aggregates by. Each is returned on every row.
Show child attributes
Show child attributes
An and/or tree of predicates over dimensions, applied before aggregation. Omit to match every row the caller can see.
Show child attributes
Show child attributes
Predicates over measures, applied after aggregation.
- InFilter[OrgHourlyWorkloadMeasures]
- ArrayContainsFilter[OrgHourlyWorkloadMeasures]
- IsFilter[OrgHourlyWorkloadMeasures]
- LikeFilter[OrgHourlyWorkloadMeasures]
- MultiLikeFilter[OrgHourlyWorkloadMeasures]
- EqFilter[OrgHourlyWorkloadMeasures]
- FilterExpression[OrgHourlyWorkloadMeasures]
- InRelativeDateRangeFilter[OrgHourlyWorkloadMeasures]
Show child attributes
Show child attributes
Ordering applied to the aggregated rows.
Show child attributes
Show child attributes
Maximum rows to return. Omit for no limit. An aggregation that produces more rows than this is silently cut short at the limit.
x >= 1Return the SQL that produced the rows alongside them, for inspecting how a result was computed. Not every query endpoint publishes its SQL; where it does not, the field stays null.
Reshape the result so the named dimensions become columns rather than rows. Each remaining dimension yields one row, carrying a pivot_data object keyed by the pivoted dimension values. Every name in pivot.on must also appear in dimensions.
Show child attributes
Show child attributes
Return the result as a tree rather than a flat list, grouping the named dimensions into one level per tree depth. One request fetches the top level; a follow-up naming rollup.parent_paths fetches the children of the nodes expanded so far, so a deep hierarchy is read a level at a time. Every name in rollup.dimensions must also appear in dimensions.
Show child attributes
Show child attributes
Aggregate the matching rows. Set false to return the underlying rows as they are, projecting the requested dimensions with no grouping — a listing rather than an aggregation. It is honored only for a request that asks for no measures and no measure_filters, since an aggregate has to group to be computable; limit, when set, bounds the rows returned either way.
Response
Successful Response
Opaque cursor for the next page; empty/absent on the last page.
Best-effort total for the filtered result set; may be null when expensive.
The SQL that produced these rows, returned only when the request asks for it. Database and schema names are left as placeholders. Null when the request did not ask for it, or when this endpoint does not publish its SQL.

