curl --request POST \
--url https://api.select.dev/v2/metrics/databricks-served-endpoints/query \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'x-tenant-id: <x-tenant-id>' \
--data '
{
"measures": [
"sum_spend",
"request_spend",
"idle_spend",
"num_requests",
"error_rate_percent",
"sum_total_tokens"
],
"dimensions": [
"endpoint_id",
"endpoint_name",
"databricks_workspace_id"
],
"filter_expression": {
"operator": "and",
"filters": [
{
"field": "day",
"operator": "in range",
"value": "30D"
}
]
},
"sort": [
{
"field": "sum_spend",
"direction": "desc"
}
],
"limit": 50
}
'{
"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 Databricks served endpoints
One row per group of Databricks model serving endpoints, carrying spend (split into request and idle spend), request counts, error rate and token throughput for each endpoint with usage over the requested period, or the list of endpoints and their configuration when only configuration fields are requested.
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 for the spend, traffic and errors of Databricks Model Serving endpoints. Usage measures return only endpoints with requests or billed usage in the period. sum_spend is dollars and splits into request_spend, billed to requests, and idle_spend, billed while the endpoint served no requests. idle_spend is the billed DBUs left after the requests that were logged, so an endpoint with billing but no request logs, such as a pay-per-token endpoint that appears only in billing, reads as entirely idle. idle_spend means unused capacity only for endpoints billed for uptime, such as provisioned endpoints. Pay-per-token endpoints are billed per token, so for them it is billed usage that no logged request accounts for, which can be large even when the endpoint logs requests. Do not read it as unused capacity for them. error_rate_percent is 0 to 100, and the sum_*_tokens measures are token counts. created_by is the creator’s display name, or the raw ID where no name is known (created_by_is_unresolved flags that case). Group by usage_group to categorize endpoints into your usage groups.
The fields in the request pick the source. endpoint_count counts the list of endpoints. It reads that list, which includes endpoints with no usage and deleted ones, and takes config and identity dimensions (entity_types, tasks, served_entity_names, entity_names, scale_to_zero_enabled, endpoint_delete_time) and usage_group. It takes no date filter, and a request that pairs it with a usage field such as day is rejected. active_endpoint_count counts endpoints with requests or billed usage in the period, and reads usage. Usage groups apply to both, but the list carries no billing fields, so a rule that uses databricks_sku_name or databricks_billing_origin_product matches no endpoint on the list while it still groups the same endpoint’s spend. Counts from the list and spend by usage group can differ for such rules. The creator comes from the endpoint’s config, so an endpoint that appears only in billing has no creator, and a rule on databricks_created_by does not match it on any source of this route. Endpoints that appear only in billing are in the list too, with their name from billing and null config dimensions. Because they have no config, endpoint_delete_time is always null for them, so they are never marked deleted, even if they last billed long ago. Naming hour or hour_of_day reads hourly data, and any other request with a usage field reads daily data. For total Model Serving spend, use spend with databricks_billing_origin_product = "Model Serving". For individual requests, use databricks-model-serving.
curl --request POST \
--url https://api.select.dev/v2/metrics/databricks-served-endpoints/query \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'x-tenant-id: <x-tenant-id>' \
--data '
{
"measures": [
"sum_spend",
"request_spend",
"idle_spend",
"num_requests",
"error_rate_percent",
"sum_total_tokens"
],
"dimensions": [
"endpoint_id",
"endpoint_name",
"databricks_workspace_id"
],
"filter_expression": {
"operator": "and",
"filters": [
{
"field": "day",
"operator": "in range",
"value": "30D"
}
]
},
"sort": [
{
"field": "sum_spend",
"direction": "desc"
}
],
"limit": 50
}
'{
"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 Databricks model serving endpoints as inventory or as usage over time.
A request with only endpoint_count, endpoint config dimensions and
usage_group reads the list of endpoints, which includes endpoints with no
usage, deleted ones, and ones that appear only in billing, whose config
dimensions are null and which are never marked deleted. A request naming any
field the list lacks, such as a usage measure, day or active_endpoint_count,
reads usage, and only endpoints with requests or billed usage in the requested
period appear. The list carries no billing fields, so a usage group rule on
databricks_sku_name or databricks_billing_origin_product matches no endpoint
there. Naming hour or hour_of_day reads hourly data;
any other usage request reads daily data.
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[DatabricksServedEndpointMeasures]
- ArrayContainsFilter[DatabricksServedEndpointMeasures]
- IsFilter[DatabricksServedEndpointMeasures]
- LikeFilter[DatabricksServedEndpointMeasures]
- MultiLikeFilter[DatabricksServedEndpointMeasures]
- EqFilter[DatabricksServedEndpointMeasures]
- FilterExpression[DatabricksServedEndpointMeasures]
- InRelativeDateRangeFilter[DatabricksServedEndpointMeasures]
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.

