# Metrics (/docs/reference/api/metrics)



Metrics [#metrics]

GET `/v1/metrics` [#get-v1metrics]

Query stored rows from the internal `default.metrics` table using a first-party
session or OAuth access token. API keys are not accepted. Select an organization
with `organization_id` or `organization`. Optionally restrict the query with
comma-separated `cluster_id` UUIDs, or a `cluster` name with `organization`.
Only clusters belonging to the authorized organization are queried.

```http
GET /v1/metrics?organization=acme&cluster=production&metric=rawtree.cluster.cpu.allocated&start_time=2026-09-22T11%3A00%3A00Z&end_time=2026-09-22T12%3A01%3A00Z
```

`metric` is a comma-separated list of exact metric names (up to 100 names, each
up to 256 bytes). It is required for aggregation; raw reads may omit it to read
all names in the selected scope and time range. New metric names require no
endpoint changes.

`filters` accepts a URL-encoded JSON object of exact field matches. For example:

```json
{
  "service.name": "rawtree-cluster-worker",
  "scope.name": "rawtree.connector.metrics",
  "rawtree.connector.id": "connector-id",
  "rawtree.connector.revision": "2"
}
```

Filter values are strings. Paths use dot-separated identifiers containing
letters, digits and underscores, with a letter or underscore first in each
segment. Up to 32 filters are supported; paths are limited to 256 bytes and
values to 1024 bytes. Filters add restrictions to the authorized tenant scope.
Use the actual stored path: cluster table metrics use `rawtree.table.name`,
while connector destinations use `db.collection.name`.

Pass `start_time` and `end_time` as RFC 3339 timestamps, or `window_seconds`
for a trailing range resolved using the server's UTC clock. The lower bound is
inclusive and the upper bound exclusive. The interval must be positive and no
longer than 31 days. Relative and explicit ranges cannot be combined.

The response body is the `data` array from the filtered
`SELECT * FROM default.metrics ... FORMAT JSON` query. It has no enclosing
`data`, `meta`, or time-window object. Columns retain their query-output names,
including dotted names such as `service.name`; absent values remain `null`.
Rows are ordered by `timeUnixNano` ascending; order among equal timestamps is
unspecified. Empty results return `[]`. Duplicate observations remain visible.

Example response (the columns shown depend on the table's schema):

```json
[
  {
    "service.name": "rawtree-cluster-worker",
    "service.namespace": "rawtree",
    "scope.name": "rawtree.cluster.metrics",
    "scope.version": "0.1.0",
    "rawtree.organization.id": "organization-id",
    "rawtree.organization.name": "acme",
    "rawtree.cluster.id": "cluster-id",
    "rawtree.cluster.name": "production",
    "metric.name": "rawtree.cluster.cpu.allocated",
    "metric.type": "gauge",
    "metric.unit": "{core}",
    "timeUnixNano": "1790078400000000000",
    "asDouble": 2.0,
    "asInt": null
  }
]
```

By default, the endpoint does not regroup rows into OTLP, sample observations, or add
baseline points outside the requested range. Query failures and results exceeding
the 90,000-row or 32 MiB response limit return HTTP 503; narrow the time range or
filters and retry. There is no partial-success response or separate metadata header.

For bucketed numeric results, pass `aggregation=avg|min|max|sum|count` and
`granularity_seconds` (1 through 2678400). Optional `group_by` selects up to eight
comma-separated dotted field paths. Metric name, type and unit, organization and
cluster IDs, service name/namespace, and scope name always remain separate groups.
Missing dimensions form a group with a `null` label. Buckets start at the requested
lower bound; the last bucket may be shorter. Empty buckets are omitted.

```http
GET /v1/metrics?organization=acme&cluster=production&metric=rawtree.cluster.memory.allocated&window_seconds=604800&aggregation=avg&granularity_seconds=5040
```

`avg`, `min`, `max`, and `sum` reduce the selected numeric observations in each
bucket and group. `count` counts scalar observations, including duplicate stored rows;
it does not measure new events in a cumulative counter. For histogram and
summary metrics, `count` counts the recorded measurements instead. `last` and
the `component` parameter are not supported.

For cumulative counters, add `function=increase` or `function=rate`. The function
runs on each original series **before** aggregation across the selected groups.
`increase` adds observed counter changes, treating a decrease or a changed nonzero
start timestamp as a reset. `rate` divides that increase by the bucket duration
in seconds. For example, `100 → 130 → 160` has increase 60, while summing the three
raw samples gives 390.

```http
GET /v1/metrics?organization=acme&cluster=production&metric=rawtree.connector.events.delivered&window_seconds=3600&function=increase&aggregation=sum&granularity_seconds=30&group_by=rawtree.connector.destination.id
```

Counter functions read up to five minutes before the range for a predecessor.
Each difference belongs to the bucket containing the later observation. Missing
predecessors and gaps longer than five minutes yield no difference. Values are
observed increases; they are not extrapolated to time-range edges as PromQL does.
Each counter series must use one numeric encoding (`asInt` or `asDouble`) across
the queried range and predecessor window; encoding changes return HTTP 400.
Identical retry samples are deduplicated for counter functions; conflicting
values for one series at the same timestamp fail the query. Distinct runtime
instances remain distinct series until their increases have been calculated.

Select a histogram or summary by its metric name and the statistic you want:

| Metric type          | Supported aggregations              | Meaning                                                                         |
| -------------------- | ----------------------------------- | ------------------------------------------------------------------------------- |
| Gauge or sum         | `avg`, `min`, `max`, `sum`, `count` | Reduce scalar observations; with a function, reduce per-series interval results |
| Histogram or summary | `avg`, `sum`, `count`               | Weighted mean (`sum / count`), total measured value, or number of measurements  |

```http
GET /v1/metrics?organization=acme&cluster=production&metric=rawtree.connector.delivery.duration&window_seconds=3600&function=increase&aggregation=avg&granularity_seconds=30&group_by=rawtree.connector.destination.id
```

This returns the mean delivery duration for each interval and destination.
Histogram and summary averages are weighted by measurement count across
observations and series. Without a function, their stored sums and counts are
added; cumulative snapshots therefore include repeated historical measurements.
Use `function=increase` for interval totals or means. For distributions,
`function=rate` supports `sum` and `count`, dividing the interval total by the
bucket duration. Distribution `min` and `max` are not supported because exact
interval extrema cannot be recovered from cumulative summaries or buckets.

`function` requires a cumulative monotonic sum, a cumulative histogram, or a
summary. Incompatible operations return HTTP 400. Histogram and summary resets
use their observation count, so sums, counts, and buckets reset together.
Summary quantiles cannot be combined. An average with zero measurements is
undefined, so that result is omitted; `sum` and `count` still return zero.

Aggregated responses are a bare array with `timeUnixNano`, `endTimeUnixNano`,
`metric`, `unit`, `kind`, `dimensions`, and `value`. The `value` is the requested
statistic. Timestamps and values are decimal strings. Integer reductions and
counter differences preserve integer precision; averages, rates and floating
point inputs use floating point arithmetic. `unit` retains the stored metric
unit; count values represent counts and rate values are per second.

Each result also contains `sum`, `count`, `bounds`, and `bucketCounts` to let
clients combine distribution statistics without averaging averages. For scalar
metrics, `sum` and `count` are `null` and both arrays are empty. For distributions,
`count` is a decimal string. `sum` is a decimal string for sum/average queries
and `null` for count queries, which do not require an optional histogram sum.
Missing histogram bucket arrays are allowed; malformed stored layouts are
rejected. With either counter function, these
supporting fields retain interval totals, even when `value` is a per-second rate.
Histogram buckets are merged when all layouts in the group match; `bounds` holds
the explicit boundaries and `bucketCounts` contains non-cumulative decimal-string
counts, including the final overflow bucket. Incompatible layouts return empty
arrays while retaining valid sums, counts, and means. A layout change does not
reset sum/count; intervals with incomplete bucket coverage also omit the arrays.
Summaries always return
empty arrays. Raw reads keep the stored-row response described above.

All aggregation options require both `aggregation` and `granularity_seconds`.
The same result limits apply: use wider buckets or narrower filters when a result
is too large. No partial result is returned.

Cluster CPU and memory charts query `system.metric_log` and
`system.asynchronous_metric_log` through `POST /v1/query`. Query-count charts
also use the Query API, reading `system.query_log`. Pass `organization`,
`cluster`, and `database=default` to select the cluster for a native system-table
query. These reads use the query credential's permissions and the native tables'
retention.

Stored cluster measurements remain available through `GET /v1/metrics` under
`rawtree.cluster.*`. Connector configuration and runtime state remain available
through `/v1/connectors/{connector_id}`.

Use a user session or user OAuth token with `full_access`. API keys and workload tokens cannot use this method.

Parameters:

| Field                 | Location | Type                                            | Required | Notes                                                                          |
| --------------------- | -------- | ----------------------------------------------- | -------- | ------------------------------------------------------------------------------ |
| `organization_id`     | query    | string or null                                  | No       | —                                                                              |
| `organization`        | query    | string or null                                  | No       | —                                                                              |
| `cluster`             | query    | string or null                                  | No       | —                                                                              |
| `cluster_id`          | query    | string or null                                  | No       | —                                                                              |
| `filters`             | query    | string or null                                  | No       | JSON object of exact-match dotted field paths and string values.               |
| `metric`              | query    | string or null                                  | No       | Comma-separated metric names; required for aggregation. Raw reads may omit it. |
| `aggregation`         | query    | null or `avg` / `min` / `max` / `sum` / `count` | No       | Numeric reduction within each time bucket and group.                           |
| `function`            | query    | null or `increase` / `rate`                     | No       | Reset-aware per-series operation, applied before aggregation.                  |
| `granularity_seconds` | query    | integer or null                                 | No       | —                                                                              |
| `group_by`            | query    | string or null                                  | No       | Additional dimensions; tenant and collector dimensions are always retained.    |
| `start_time`          | query    | string or null                                  | No       | —                                                                              |
| `end_time`            | query    | string or null                                  | No       | —                                                                              |
| `window_seconds`      | query    | integer or null                                 | No       | Trailing interval resolved against server UTC; excludes explicit timestamps.   |

Request:

```bash
# Read stored metric rows with mandatory tenant authorization and exact field filters.
curl -X GET "https://api.rawtree.com/v1/metrics?organization=team_alpha&cluster=production&window_seconds=3600" \
  -H "Authorization: Bearer $RAWTREE_USER_TOKEN"
```

Expected response: **HTTP 200**.

```json
[]
```

Errors: `400`, `401`, `403`, `503`. See [API errors](/docs/reference/errors).
